1e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org// Copyright 2013 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.
4a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen.h"
6a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org#include <algorithm>
8ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/allocation-site-scopes.h"
11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h"
12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/full-codegen.h"
13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hashmap.h"
14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-bce.h"
15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-bch.h"
16196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-canonicalize.h"
17196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-check-elimination.h"
18196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-dce.h"
19196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-dehoist.h"
20196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-environment-liveness.h"
21196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-escape-analysis.h"
22196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-infer-representation.h"
23196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-infer-types.h"
24196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-load-elimination.h"
25196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-gvn.h"
26196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-mark-deoptimize.h"
27196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-mark-unreachable.h"
28196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-osr.h"
29196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-range-analysis.h"
30196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-redundant-phi.h"
31196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-removable-simulates.h"
32196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-representation-changes.h"
33196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-sce.h"
34196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-store-elimination.h"
35196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-uint32-analysis.h"
36196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/lithium-allocator.h"
37196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/parser.h"
38196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/runtime.h"
39196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/scopeinfo.h"
40196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/scopes.h"
41196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/stub-cache.h"
42196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/typing.h"
43a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
44a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#if V8_TARGET_ARCH_IA32
45196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/ia32/lithium-codegen-ia32.h"
46a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#elif V8_TARGET_ARCH_X64
47196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/x64/lithium-codegen-x64.h"
48fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org#elif V8_TARGET_ARCH_ARM64
49196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/arm64/lithium-codegen-arm64.h"
50a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#elif V8_TARGET_ARCH_ARM
51196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/arm/lithium-codegen-arm.h"
527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#elif V8_TARGET_ARCH_MIPS
53196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/mips/lithium-codegen-mips.h"
54864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#elif V8_TARGET_ARCH_X87
55196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/x87/lithium-codegen-x87.h"
56a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#else
57a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#error Unsupported target architecture.
58a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif
59a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
60a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace v8 {
61a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace internal {
62a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
63a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgHBasicBlock::HBasicBlock(HGraph* graph)
64a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    : block_id_(graph->GetNextBlockID()),
65a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      graph_(graph),
667028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      phis_(4, graph->zone()),
67a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      first_(NULL),
68a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      last_(NULL),
69a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      end_(NULL),
70a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      loop_information_(NULL),
717028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      predecessors_(2, graph->zone()),
72a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      dominator_(NULL),
737028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      dominated_blocks_(4, graph->zone()),
74a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      last_environment_(NULL),
75a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      argument_count_(-1),
76a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      first_instruction_index_(-1),
77a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      last_instruction_index_(-1),
787028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      deleted_phis_(4, graph->zone()),
79496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org      parent_loop_header_(NULL),
80d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      inlined_entry_block_(NULL),
816d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      is_inline_return_target_(false),
82d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org      is_reachable_(true),
837c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      dominates_loop_successors_(false),
8454ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org      is_osr_entry_(false),
8554ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org      is_ordered_(false) { }
86a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
87a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
88750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgIsolate* HBasicBlock::isolate() const {
89750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  return graph_->isolate();
90750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org}
91750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
92750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
93d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgvoid HBasicBlock::MarkUnreachable() {
94d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  is_reachable_ = false;
95d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org}
96d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
97d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
98a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HBasicBlock::AttachLoopInformation() {
99a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(!IsLoopHeader());
1007028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  loop_information_ = new(zone()) HLoopInformation(this, zone());
101a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
102a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
103a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
104a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HBasicBlock::DetachLoopInformation() {
105a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(IsLoopHeader());
106a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  loop_information_ = NULL;
107a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
108a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
109a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
110a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HBasicBlock::AddPhi(HPhi* phi) {
111a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(!IsStartBlock());
1127028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  phis_.Add(phi, zone());
113a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  phi->SetBlock(this);
114a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
115a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
116a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
117a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HBasicBlock::RemovePhi(HPhi* phi) {
118a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(phi->block() == this);
119a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(phis_.Contains(phi));
120ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  phi->Kill();
121a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  phis_.RemoveElement(phi);
122a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  phi->SetBlock(NULL);
123a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
124a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
125a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
126f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid HBasicBlock::AddInstruction(HInstruction* instr,
127f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                 HSourcePosition position) {
128a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(!IsStartBlock() || !IsFinished());
129a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(!instr->IsLinked());
130a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(!IsFinished());
131b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
132f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (!position.IsUnknown()) {
13371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    instr->set_position(position);
13471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  }
135a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (first_ == NULL) {
136b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    ASSERT(last_environment() != NULL);
137b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    ASSERT(!last_environment()->ast_id().IsNone());
13874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org    HBlockEntry* entry = new(zone()) HBlockEntry();
139a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    entry->InitializeAsFirst(this);
140f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (!position.IsUnknown()) {
14171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org      entry->set_position(position);
14271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    } else {
143f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      ASSERT(!FLAG_hydrogen_track_positions ||
14471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org             !graph()->info()->IsOptimizing());
14571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    }
14649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    first_ = last_ = entry;
147a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
14849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  instr->InsertAfter(last_);
149a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
150a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
151a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
152ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.orgHPhi* HBasicBlock::AddNewPhi(int merged_index) {
153ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org  if (graph()->IsInsideNoSideEffectsScope()) {
154ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org    merged_index = HPhi::kInvalidMergedIndex;
155ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org  }
156ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org  HPhi* phi = new(zone()) HPhi(merged_index, zone());
157ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org  AddPhi(phi);
158ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org  return phi;
159ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org}
160ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org
161ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org
162fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgHSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id,
163fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                                       RemovableSimulate removable) {
164a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(HasEnvironment());
165a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HEnvironment* environment = last_environment();
166471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  ASSERT(ast_id.IsNone() ||
167a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org         ast_id == BailoutId::StubEntry() ||
16804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org         environment->closure()->shared()->VerifyBailoutId(ast_id));
169a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
170a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int push_count = environment->push_count();
171a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int pop_count = environment->pop_count();
172a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
173fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  HSimulate* instr =
174fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      new(zone()) HSimulate(ast_id, pop_count, zone(), removable);
175d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org#ifdef DEBUG
176d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  instr->set_closure(environment->closure());
177d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org#endif
178fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  // Order of pushed values: newest (top of stack) first. This allows
179a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  // HSimulate::MergeWith() to easily append additional pushed values
180fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  // that are older (from further down the stack).
181fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  for (int i = 0; i < push_count; ++i) {
182a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    instr->AddPushedValue(environment->ExpressionStackAt(i));
183a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
18459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  for (GrowableBitVector::Iterator it(environment->assigned_variables(),
18559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                                      zone());
18659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org       !it.Done();
18759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org       it.Advance()) {
18859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    int index = it.Current();
189a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    instr->AddAssignedValue(index, environment->Lookup(index));
190a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
191a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  environment->ClearHistory();
192a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return instr;
193a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
194a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
195a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
196f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid HBasicBlock::Finish(HControlInstruction* end, HSourcePosition position) {
197a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(!IsFinished());
19871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  AddInstruction(end, position);
199a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  end_ = end;
2006d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  for (HSuccessorIterator it(end); !it.Done(); it.Advance()) {
2016d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    it.Current()->RegisterPredecessor(this);
202a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
203a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
204a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
205a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
206b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgvoid HBasicBlock::Goto(HBasicBlock* block,
207f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                       HSourcePosition position,
208b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org                       FunctionState* state,
209b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org                       bool add_simulate) {
210471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  bool drop_extra = state != NULL &&
211a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      state->inlining_kind() == NORMAL_RETURN;
21228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
2134d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  if (block->IsInlineReturnTarget()) {
214d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    HEnvironment* env = last_environment();
215d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    int argument_count = env->arguments_environment()->parameter_count();
21671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    AddInstruction(new(zone())
21771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org                   HLeaveInlined(state->entry(), argument_count),
21871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org                   position);
219d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    UpdateEnvironment(last_environment()->DiscardInlined(drop_extra));
2204d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  }
22128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
22271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  if (add_simulate) AddNewSimulate(BailoutId::None(), position);
22374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  HGoto* instr = new(zone()) HGoto(block);
22471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  Finish(instr, position);
225a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
226a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
227a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
228394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid HBasicBlock::AddLeaveInlined(HValue* return_value,
22971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org                                  FunctionState* state,
230f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                  HSourcePosition position) {
231471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  HBasicBlock* target = state->function_return();
232a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  bool drop_extra = state->inlining_kind() == NORMAL_RETURN;
23328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
2344d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  ASSERT(target->IsInlineReturnTarget());
2354d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  ASSERT(return_value != NULL);
236d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  HEnvironment* env = last_environment();
237d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  int argument_count = env->arguments_environment()->parameter_count();
23871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  AddInstruction(new(zone()) HLeaveInlined(state->entry(), argument_count),
23971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org                 position);
240d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  UpdateEnvironment(last_environment()->DiscardInlined(drop_extra));
2414d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  last_environment()->Push(return_value);
24271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  AddNewSimulate(BailoutId::None(), position);
24374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  HGoto* instr = new(zone()) HGoto(target);
24471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  Finish(instr, position);
2454d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org}
2464d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org
2474d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org
248b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgvoid HBasicBlock::SetInitialEnvironment(HEnvironment* env) {
249a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(!HasEnvironment());
250a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(first() == NULL);
251a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  UpdateEnvironment(env);
252a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
253a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
254a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
255d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgvoid HBasicBlock::UpdateEnvironment(HEnvironment* env) {
256d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  last_environment_ = env;
257d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  graph()->update_maximum_environment_size(env->first_expression_index());
258d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org}
259d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
260d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
261471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid HBasicBlock::SetJoinId(BailoutId ast_id) {
262a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int length = predecessors_.length();
263a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(length > 0);
264a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < length; i++) {
265a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    HBasicBlock* predecessor = predecessors_[i];
266a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(predecessor->end()->IsGoto());
26749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org    HSimulate* simulate = HSimulate::cast(predecessor->end()->previous());
268a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(i != 0 ||
26994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org           (predecessor->last_environment()->closure().is_null() ||
27094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org            predecessor->last_environment()->closure()->shared()
27194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org              ->VerifyBailoutId(ast_id)));
27204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    simulate->set_ast_id(ast_id);
273b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    predecessor->last_environment()->set_ast_id(ast_id);
274a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
275a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
276a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
277a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
278a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgbool HBasicBlock::Dominates(HBasicBlock* other) const {
279a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HBasicBlock* current = other->dominator();
280a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  while (current != NULL) {
281a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (current == this) return true;
282a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    current = current->dominator();
283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
284a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return false;
285a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
286a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
287a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
28857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.orgbool HBasicBlock::EqualToOrDominates(HBasicBlock* other) const {
28957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  if (this == other) return true;
29057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  return Dominates(other);
29157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org}
29257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
29357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
29483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.orgint HBasicBlock::LoopNestingDepth() const {
29583e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  const HBasicBlock* current = this;
29683e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  int result  = (current->IsLoopHeader()) ? 1 : 0;
29783e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  while (current->parent_loop_header() != NULL) {
29883e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org    current = current->parent_loop_header();
29983e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org    result++;
30083e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  }
30183e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  return result;
30283e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org}
30383e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org
30483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org
305a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HBasicBlock::PostProcessLoopHeader(IterationStatement* stmt) {
306a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(IsLoopHeader());
307a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
308a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SetJoinId(stmt->EntryId());
309a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (predecessors()->length() == 1) {
310a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // This is a degenerated loop.
311a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    DetachLoopInformation();
312a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return;
313a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
314a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
315a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Only the first entry into the loop is from outside the loop. All other
316a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // entries must be back edges.
317a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 1; i < predecessors()->length(); ++i) {
318a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    loop_information()->RegisterBackEdge(predecessors()->at(i));
319a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
320a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
321a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
322a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
323f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid HBasicBlock::MarkSuccEdgeUnreachable(int succ) {
324f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  ASSERT(IsFinished());
325f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  HBasicBlock* succ_block = end()->SuccessorAt(succ);
326f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
327f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  ASSERT(succ_block->predecessors()->length() == 1);
328f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  succ_block->MarkUnreachable();
329f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
330f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
331f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
332a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HBasicBlock::RegisterPredecessor(HBasicBlock* pred) {
333160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  if (HasPredecessor()) {
334a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Only loop header blocks can have a predecessor added after
335a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // instructions have been added to the block (they have phis for all
336a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // values in the environment, these phis may be eliminated later).
337a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(IsLoopHeader() || first_ == NULL);
338a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    HEnvironment* incoming_env = pred->last_environment();
339a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (IsLoopHeader()) {
3405d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org      ASSERT(phis()->length() == incoming_env->length());
341a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      for (int i = 0; i < phis_.length(); ++i) {
342a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        phis_[i]->AddInput(incoming_env->values()->at(i));
343a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
344a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    } else {
345a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      last_environment()->AddIncomingEdge(this, pred->last_environment());
346a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
347a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else if (!HasEnvironment() && !IsFinished()) {
348a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(!IsLoopHeader());
349b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    SetInitialEnvironment(pred->last_environment()->Copy());
350a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
351a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3527028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  predecessors_.Add(pred, zone());
353a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
354a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
355a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
356a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HBasicBlock::AddDominatedBlock(HBasicBlock* block) {
357a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(!dominated_blocks_.Contains(block));
358a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Keep the list of dominated blocks sorted such that if there is two
359a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // succeeding block in this list, the predecessor is before the successor.
360a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int index = 0;
361a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  while (index < dominated_blocks_.length() &&
362a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org         dominated_blocks_[index]->block_id() < block->block_id()) {
363a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ++index;
364a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
3657028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  dominated_blocks_.InsertAt(index, block, zone());
366a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
367a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
368a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
369a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HBasicBlock::AssignCommonDominator(HBasicBlock* other) {
370a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (dominator_ == NULL) {
371a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    dominator_ = other;
372a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    other->AddDominatedBlock(this);
373a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else if (other->dominator() != NULL) {
374a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    HBasicBlock* first = dominator_;
375a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    HBasicBlock* second = other;
376a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
377a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    while (first != second) {
378a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      if (first->block_id() > second->block_id()) {
379a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        first = first->dominator();
380a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      } else {
381a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        second = second->dominator();
382a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
383a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      ASSERT(first != NULL && second != NULL);
384a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
385a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
386a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (dominator_ != first) {
387a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      ASSERT(dominator_->dominated_blocks_.Contains(this));
388a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      dominator_->dominated_blocks_.RemoveElement(this);
389a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      dominator_ = first;
390a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      first->AddDominatedBlock(this);
391a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
392a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
393a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
394a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
395a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
39678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.orgvoid HBasicBlock::AssignLoopSuccessorDominators() {
39778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  // Mark blocks that dominate all subsequent reachable blocks inside their
39878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  // loop. Exploit the fact that blocks are sorted in reverse post order. When
39978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  // the loop is visited in increasing block id order, if the number of
40078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  // non-loop-exiting successor edges at the dominator_candidate block doesn't
40178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  // exceed the number of previously encountered predecessor edges, there is no
40278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  // path from the loop header to any block with higher id that doesn't go
40378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  // through the dominator_candidate block. In this case, the
40478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  // dominator_candidate block is guaranteed to dominate all blocks reachable
40578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  // from it with higher ids.
40678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  HBasicBlock* last = loop_information()->GetLastBackEdge();
40778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  int outstanding_successors = 1;  // one edge from the pre-header
40878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  // Header always dominates everything.
40978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  MarkAsLoopSuccessorDominator();
41078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  for (int j = block_id(); j <= last->block_id(); ++j) {
41178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    HBasicBlock* dominator_candidate = graph_->blocks()->at(j);
41278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    for (HPredecessorIterator it(dominator_candidate); !it.Done();
41378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org         it.Advance()) {
41478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      HBasicBlock* predecessor = it.Current();
41578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      // Don't count back edges.
41678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      if (predecessor->block_id() < dominator_candidate->block_id()) {
41778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org        outstanding_successors--;
41878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      }
41978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    }
42078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
42178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    // If more successors than predecessors have been seen in the loop up to
42278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    // now, it's not possible to guarantee that the current block dominates
42378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    // all of the blocks with higher IDs. In this case, assume conservatively
42478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    // that those paths through loop that don't go through the current block
42578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    // contain all of the loop's dependencies. Also be careful to record
42678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    // dominator information about the current loop that's being processed,
42778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    // and not nested loops, which will be processed when
42878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    // AssignLoopSuccessorDominators gets called on their header.
42978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    ASSERT(outstanding_successors >= 0);
43078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    HBasicBlock* parent_loop_header = dominator_candidate->parent_loop_header();
43178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    if (outstanding_successors == 0 &&
43278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org        (parent_loop_header == this && !dominator_candidate->IsLoopHeader())) {
43378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      dominator_candidate->MarkAsLoopSuccessorDominator();
43478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    }
43578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    HControlInstruction* end = dominator_candidate->end();
43678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    for (HSuccessorIterator it(end); !it.Done(); it.Advance()) {
43778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      HBasicBlock* successor = it.Current();
43878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      // Only count successors that remain inside the loop and don't loop back
43978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      // to a loop header.
44078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      if (successor->block_id() > dominator_candidate->block_id() &&
44178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org          successor->block_id() <= last->block_id()) {
44278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org        // Backwards edges must land on loop headers.
44378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org        ASSERT(successor->block_id() > dominator_candidate->block_id() ||
44478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org               successor->IsLoopHeader());
44578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org        outstanding_successors++;
44678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      }
44778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    }
44878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  }
44978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org}
45078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
45178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
452a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgint HBasicBlock::PredecessorIndexOf(HBasicBlock* predecessor) const {
453a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < predecessors_.length(); ++i) {
454a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (predecessors_[i] == predecessor) return i;
455a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
456a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  UNREACHABLE();
457a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return -1;
458a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
459a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
460a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
461a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifdef DEBUG
462a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HBasicBlock::Verify() {
463a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Check that every block is finished.
464a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(IsFinished());
465a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(block_id() >= 0);
4664d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org
4674d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  // Check that the incoming edges are in edge split form.
4684d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  if (predecessors_.length() > 1) {
4694d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    for (int i = 0; i < predecessors_.length(); ++i) {
4704d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org      ASSERT(predecessors_[i]->end()->SecondSuccessor() == NULL);
4714d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    }
4724d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  }
473a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
474a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif
475a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
476a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
477a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HLoopInformation::RegisterBackEdge(HBasicBlock* block) {
4787028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  this->back_edges_.Add(block, block->zone());
479a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  AddBlock(block);
480a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
481a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
482a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
483a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgHBasicBlock* HLoopInformation::GetLastBackEdge() const {
484a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int max_id = -1;
485a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HBasicBlock* result = NULL;
486a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < back_edges_.length(); ++i) {
487a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    HBasicBlock* cur = back_edges_[i];
488a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (cur->block_id() > max_id) {
489a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      max_id = cur->block_id();
490a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      result = cur;
491a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
492a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
493a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return result;
494a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
495a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
496a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
497a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HLoopInformation::AddBlock(HBasicBlock* block) {
498a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (block == loop_header()) return;
499a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (block->parent_loop_header() == loop_header()) return;
500a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (block->parent_loop_header() != NULL) {
501a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    AddBlock(block->parent_loop_header());
502a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
503a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    block->set_parent_loop_header(loop_header());
5047028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    blocks_.Add(block, block->zone());
505a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    for (int i = 0; i < block->predecessors()->length(); ++i) {
506a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      AddBlock(block->predecessors()->at(i));
507a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
508a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
509a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
510a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
511a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
512a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifdef DEBUG
513a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
514a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Checks reachability of the blocks in this graph and stores a bit in
515a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// the BitVector "reachable()" for every block that can be reached
516a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// from the start block of the graph. If "dont_visit" is non-null, the given
517a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// block is treated as if it would not be part of the graph. "visited_count()"
518a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// returns the number of reachable blocks.
519a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass ReachabilityAnalyzer BASE_EMBEDDED {
520a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
521a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ReachabilityAnalyzer(HBasicBlock* entry_block,
522a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                       int block_count,
523a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                       HBasicBlock* dont_visit)
524a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      : visited_count_(0),
5257028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        stack_(16, entry_block->zone()),
5267028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        reachable_(block_count, entry_block->zone()),
527a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        dont_visit_(dont_visit) {
528a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    PushBlock(entry_block);
529a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Analyze();
530a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
531a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
532a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int visited_count() const { return visited_count_; }
533a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  const BitVector* reachable() const { return &reachable_; }
534a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
535a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
536a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void PushBlock(HBasicBlock* block) {
537a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (block != NULL && block != dont_visit_ &&
538a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        !reachable_.Contains(block->block_id())) {
539a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      reachable_.Add(block->block_id());
5407028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      stack_.Add(block, block->zone());
541a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      visited_count_++;
542a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
543a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
544a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
545a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void Analyze() {
546a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    while (!stack_.is_empty()) {
547a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      HControlInstruction* end = stack_.RemoveLast()->end();
5486d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      for (HSuccessorIterator it(end); !it.Done(); it.Advance()) {
5496d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org        PushBlock(it.Current());
5506d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      }
551a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
552a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
553a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
554a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int visited_count_;
555a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ZoneList<HBasicBlock*> stack_;
556a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  BitVector reachable_;
557a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HBasicBlock* dont_visit_;
558a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
559a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
560a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
561c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid HGraph::Verify(bool do_full_verify) const {
5621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Heap::RelocationLock relocation_lock(isolate()->heap());
5631fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  AllowHandleDereference allow_deref;
56479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  AllowDeferredHandleDereference allow_deferred_deref;
565a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < blocks_.length(); i++) {
566a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    HBasicBlock* block = blocks_.at(i);
567a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
568a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    block->Verify();
569a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
570a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Check that every block contains at least one node and that only the last
571a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // node is a control instruction.
572a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    HInstruction* current = block->first();
573a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(current != NULL && current->IsBlockEntry());
574a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    while (current != NULL) {
575a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      ASSERT((current->next() == NULL) == current->IsControlInstruction());
576a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      ASSERT(current->block() == block);
577a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      current->Verify();
578a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      current = current->next();
579a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
580a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
581a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Check that successors are correctly set.
582a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    HBasicBlock* first = block->end()->FirstSuccessor();
583a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    HBasicBlock* second = block->end()->SecondSuccessor();
584a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(second == NULL || first != NULL);
585a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
586a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Check that the predecessor array is correct.
587a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (first != NULL) {
588a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      ASSERT(first->predecessors()->Contains(block));
589a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      if (second != NULL) {
590a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        ASSERT(second->predecessors()->Contains(block));
591a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
592a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
593a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
594a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Check that phis have correct arguments.
595a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    for (int j = 0; j < block->phis()->length(); j++) {
596a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      HPhi* phi = block->phis()->at(j);
597a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      phi->Verify();
598a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
599b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
600b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    // Check that all join blocks have predecessors that end with an
601b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    // unconditional goto and agree on their environment node id.
602b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    if (block->predecessors()->length() >= 2) {
603b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      BailoutId id =
604b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org          block->predecessors()->first()->last_environment()->ast_id();
605b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      for (int k = 0; k < block->predecessors()->length(); k++) {
606b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org        HBasicBlock* predecessor = block->predecessors()->at(k);
607ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org        ASSERT(predecessor->end()->IsGoto() ||
608ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org               predecessor->end()->IsDeoptimize());
609b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org        ASSERT(predecessor->last_environment()->ast_id() == id);
610b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      }
611b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    }
612a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
613a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
614a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Check special property of first block to have no predecessors.
615a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(blocks_.at(0)->predecessors()->is_empty());
616a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
617c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (do_full_verify) {
618c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Check that the graph is fully connected.
619c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ReachabilityAnalyzer analyzer(entry_block_, blocks_.length(), NULL);
620c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT(analyzer.visited_count() == blocks_.length());
621a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
622c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Check that entry block dominator is NULL.
623c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT(entry_block_->dominator() == NULL);
624a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
625c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Check dominators.
626c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    for (int i = 0; i < blocks_.length(); ++i) {
627c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      HBasicBlock* block = blocks_.at(i);
628c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (block->dominator() == NULL) {
629c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // Only start block may have no dominator assigned to.
630c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        ASSERT(i == 0);
631c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      } else {
632c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // Assert that block is unreachable if dominator must not be visited.
633c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        ReachabilityAnalyzer dominator_analyzer(entry_block_,
634c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                                blocks_.length(),
635c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                                block->dominator());
636c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        ASSERT(!dominator_analyzer.reachable()->Contains(block->block_id()));
637c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
638a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
639a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
640a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
641a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
642a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif
643a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
644a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
645b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.orgHConstant* HGraph::GetConstant(SetOncePointer<HConstant>* pointer,
646b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org                               int32_t value) {
647657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  if (!pointer->is_set()) {
648d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    // Can't pass GetInvalidContext() to HConstant::New, because that will
649d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    // recursively call GetConstant
650d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    HConstant* constant = HConstant::New(zone(), NULL, value);
65171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    constant->InsertAfter(entry_block()->first());
652657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org    pointer->set(constant);
65371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    return constant;
65471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  }
65571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  return ReinsertConstantIfNecessary(pointer->get());
65671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org}
65771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org
65871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org
65971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.orgHConstant* HGraph::ReinsertConstantIfNecessary(HConstant* constant) {
66071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  if (!constant->IsLinked()) {
66171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    // The constant was removed from the graph. Reinsert.
66271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    constant->ClearFlag(HValue::kIsDead);
66371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    constant->InsertAfter(entry_block()->first());
664657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  }
66571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  return constant;
666657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org}
667657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
668657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
66994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgHConstant* HGraph::GetConstant0() {
670b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  return GetConstant(&constant_0_, 0);
67194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org}
67294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
67394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
674a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgHConstant* HGraph::GetConstant1() {
675b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  return GetConstant(&constant_1_, 1);
676a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
677a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
678a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
679a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgHConstant* HGraph::GetConstantMinus1() {
680b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  return GetConstant(&constant_minus1_, -1);
681a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
682a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
683a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
68429699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org#define DEFINE_GET_CONSTANT(Name, name, type, htype, boolean_value)            \
6852bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgHConstant* HGraph::GetConstant##Name() {                                       \
6862bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  if (!constant_##name##_.is_set()) {                                          \
6872bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    HConstant* constant = new(zone()) HConstant(                               \
6883d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org        Unique<Object>::CreateImmovable(isolate()->factory()->name##_value()), \
68929699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org        Unique<Map>::CreateImmovable(isolate()->factory()->type##_map()),      \
69029699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org        false,                                                                 \
6912bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org        Representation::Tagged(),                                              \
6922bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org        htype,                                                                 \
693f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org        true,                                                                  \
694bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org        boolean_value,                                                         \
695e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org        false,                                                                 \
696bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org        ODDBALL_TYPE);                                                         \
69771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    constant->InsertAfter(entry_block()->first());                             \
6982bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    constant_##name##_.set(constant);                                          \
6992bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  }                                                                            \
70071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  return ReinsertConstantIfNecessary(constant_##name##_.get());                \
701a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
702a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
703a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
704eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.orgDEFINE_GET_CONSTANT(Undefined, undefined, undefined, HType::Undefined(), false)
70529699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.orgDEFINE_GET_CONSTANT(True, true, boolean, HType::Boolean(), true)
70629699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.orgDEFINE_GET_CONSTANT(False, false, boolean, HType::Boolean(), false)
707eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.orgDEFINE_GET_CONSTANT(Hole, the_hole, the_hole, HType::None(), false)
708eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.orgDEFINE_GET_CONSTANT(Null, null, null, HType::Null(), false)
709ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
710ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
7112bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org#undef DEFINE_GET_CONSTANT
712d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org
713935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org#define DEFINE_IS_CONSTANT(Name, name)                                         \
714935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgbool HGraph::IsConstant##Name(HConstant* constant) {                           \
715935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  return constant_##name##_.is_set() && constant == constant_##name##_.get();  \
716935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org}
717935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgDEFINE_IS_CONSTANT(Undefined, undefined)
718935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgDEFINE_IS_CONSTANT(0, 0)
719935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgDEFINE_IS_CONSTANT(1, 1)
720935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgDEFINE_IS_CONSTANT(Minus1, minus1)
721935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgDEFINE_IS_CONSTANT(True, true)
722935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgDEFINE_IS_CONSTANT(False, false)
723935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgDEFINE_IS_CONSTANT(Hole, the_hole)
724935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgDEFINE_IS_CONSTANT(Null, null)
725935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org
726935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org#undef DEFINE_IS_CONSTANT
727935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org
728d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org
729876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.orgHConstant* HGraph::GetInvalidContext() {
730b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  return GetConstant(&constant_invalid_context_, 0xFFFFC0C7);
731876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org}
732876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org
733876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org
734e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.orgbool HGraph::IsStandardConstant(HConstant* constant) {
735935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  if (IsConstantUndefined(constant)) return true;
736935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  if (IsConstant0(constant)) return true;
737935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  if (IsConstant1(constant)) return true;
738935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  if (IsConstantMinus1(constant)) return true;
739935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  if (IsConstantTrue(constant)) return true;
740935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  if (IsConstantFalse(constant)) return true;
741935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  if (IsConstantHole(constant)) return true;
742935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  if (IsConstantNull(constant)) return true;
743e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  return false;
744e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org}
745e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
746e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
74771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.orgHGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder)
74894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    : builder_(builder),
74994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      finished_(false),
750b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      did_then_(false),
7517bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org      did_else_(false),
752ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      did_else_if_(false),
753b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      did_and_(false),
754b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      did_or_(false),
755b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      captured_(false),
756b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      needs_compare_(true),
757ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      pending_merge_block_(false),
758c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org      split_edge_merge_block_(NULL),
759ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      merge_at_join_blocks_(NULL),
760ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      normal_merge_at_join_block_count_(0),
761ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      deopt_merge_at_join_block_count_(0) {
76294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  HEnvironment* env = builder->environment();
763b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  first_true_block_ = builder->CreateBasicBlock(env->Copy());
764b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  first_false_block_ = builder->CreateBasicBlock(env->Copy());
76594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org}
76694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
76794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
768b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgHGraphBuilder::IfBuilder::IfBuilder(
769b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    HGraphBuilder* builder,
770b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    HIfContinuation* continuation)
771b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    : builder_(builder),
772b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      finished_(false),
773b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      did_then_(false),
774b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      did_else_(false),
775ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      did_else_if_(false),
776b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      did_and_(false),
777b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      did_or_(false),
778b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      captured_(false),
779b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      needs_compare_(false),
780ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      pending_merge_block_(false),
781b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      first_true_block_(NULL),
782b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      first_false_block_(NULL),
783b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      split_edge_merge_block_(NULL),
784ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      merge_at_join_blocks_(NULL),
785ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      normal_merge_at_join_block_count_(0),
786ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      deopt_merge_at_join_block_count_(0) {
787b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  continuation->Continue(&first_true_block_,
78871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org                         &first_false_block_);
789b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org}
790b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
791b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
792528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgHControlInstruction* HGraphBuilder::IfBuilder::AddCompare(
793528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    HControlInstruction* compare) {
794ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  ASSERT(did_then_ == did_else_);
795ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  if (did_else_) {
796ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    // Handle if-then-elseif
797ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    did_else_if_ = true;
798ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    did_else_ = false;
799ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    did_then_ = false;
800ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    did_and_ = false;
801ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    did_or_ = false;
802ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    pending_merge_block_ = false;
803ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    split_edge_merge_block_ = NULL;
804ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    HEnvironment* env = builder_->environment();
805ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    first_true_block_ = builder_->CreateBasicBlock(env->Copy());
806ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    first_false_block_ = builder_->CreateBasicBlock(env->Copy());
807ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  }
808b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  if (split_edge_merge_block_ != NULL) {
809b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    HEnvironment* env = first_false_block_->last_environment();
810b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    HBasicBlock* split_edge =
811b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org        builder_->CreateBasicBlock(env->Copy());
812b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    if (did_or_) {
813b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      compare->SetSuccessorAt(0, split_edge);
814b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      compare->SetSuccessorAt(1, first_false_block_);
815b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    } else {
816b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      compare->SetSuccessorAt(0, first_true_block_);
817b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      compare->SetSuccessorAt(1, split_edge);
818b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    }
81971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    builder_->GotoNoSimulate(split_edge, split_edge_merge_block_);
820b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  } else {
821b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    compare->SetSuccessorAt(0, first_true_block_);
822b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    compare->SetSuccessorAt(1, first_false_block_);
823b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  }
82471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  builder_->FinishCurrentBlock(compare);
825b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  needs_compare_ = false;
826528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  return compare;
827b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org}
828b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
829b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
830b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgvoid HGraphBuilder::IfBuilder::Or() {
831db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org  ASSERT(!needs_compare_);
832b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  ASSERT(!did_and_);
833b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  did_or_ = true;
834b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  HEnvironment* env = first_false_block_->last_environment();
835b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  if (split_edge_merge_block_ == NULL) {
836b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    split_edge_merge_block_ =
837b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org        builder_->CreateBasicBlock(env->Copy());
83871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    builder_->GotoNoSimulate(first_true_block_, split_edge_merge_block_);
839b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    first_true_block_ = split_edge_merge_block_;
840b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  }
841b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  builder_->set_current_block(first_false_block_);
842b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  first_false_block_ = builder_->CreateBasicBlock(env->Copy());
843b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org}
844b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
845b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
846b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgvoid HGraphBuilder::IfBuilder::And() {
847db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org  ASSERT(!needs_compare_);
848b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  ASSERT(!did_or_);
849b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  did_and_ = true;
850b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  HEnvironment* env = first_false_block_->last_environment();
851b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  if (split_edge_merge_block_ == NULL) {
852b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    split_edge_merge_block_ = builder_->CreateBasicBlock(env->Copy());
85371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    builder_->GotoNoSimulate(first_false_block_, split_edge_merge_block_);
854b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    first_false_block_ = split_edge_merge_block_;
855b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  }
856b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  builder_->set_current_block(first_true_block_);
857b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  first_true_block_ = builder_->CreateBasicBlock(env->Copy());
858b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org}
859b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
860b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
861b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgvoid HGraphBuilder::IfBuilder::CaptureContinuation(
862b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    HIfContinuation* continuation) {
863ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  ASSERT(!did_else_if_);
864b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  ASSERT(!finished_);
865b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  ASSERT(!captured_);
866ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
867ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  HBasicBlock* true_block = NULL;
868ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  HBasicBlock* false_block = NULL;
869ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  Finish(&true_block, &false_block);
870ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  ASSERT(true_block != NULL);
871ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  ASSERT(false_block != NULL);
87271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  continuation->Capture(true_block, false_block);
873b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  captured_ = true;
874ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  builder_->set_current_block(NULL);
875b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  End();
876b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org}
877b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
878b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
879528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid HGraphBuilder::IfBuilder::JoinContinuation(HIfContinuation* continuation) {
880ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  ASSERT(!did_else_if_);
881528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  ASSERT(!finished_);
882528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  ASSERT(!captured_);
883ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  HBasicBlock* true_block = NULL;
884ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  HBasicBlock* false_block = NULL;
885ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  Finish(&true_block, &false_block);
886ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  merge_at_join_blocks_ = NULL;
887528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (true_block != NULL && !true_block->IsFinished()) {
888528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    ASSERT(continuation->IsTrueReachable());
88971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    builder_->GotoNoSimulate(true_block, continuation->true_branch());
890528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
891528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (false_block != NULL && !false_block->IsFinished()) {
892528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    ASSERT(continuation->IsFalseReachable());
89371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    builder_->GotoNoSimulate(false_block, continuation->false_branch());
894528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
895528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  captured_ = true;
896528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  End();
897528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org}
898528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
899528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
900b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgvoid HGraphBuilder::IfBuilder::Then() {
901b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  ASSERT(!captured_);
902b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  ASSERT(!finished_);
903b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  did_then_ = true;
904b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  if (needs_compare_) {
905b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    // Handle if's without any expressions, they jump directly to the "else"
906d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    // branch. However, we must pretend that the "then" branch is reachable,
907d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    // so that the graph builder visits it and sees any live range extending
908d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    // constructs within it.
909d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    HConstant* constant_false = builder_->graph()->GetConstantFalse();
9101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    ToBooleanStub::Types boolean_type = ToBooleanStub::Types();
911d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    boolean_type.Add(ToBooleanStub::BOOLEAN);
912528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    HBranch* branch = builder()->New<HBranch>(
913528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        constant_false, boolean_type, first_true_block_, first_false_block_);
91471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    builder_->FinishCurrentBlock(branch);
915b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  }
9167bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  builder_->set_current_block(first_true_block_);
917ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  pending_merge_block_ = true;
9187bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org}
9197bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
9207bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
921b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgvoid HGraphBuilder::IfBuilder::Else() {
922b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  ASSERT(did_then_);
923b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  ASSERT(!captured_);
924b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  ASSERT(!finished_);
925ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  AddMergeAtJoinBlock(false);
92609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  builder_->set_current_block(first_false_block_);
927ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  pending_merge_block_ = true;
9287bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  did_else_ = true;
92994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org}
93094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
93194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
932594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid HGraphBuilder::IfBuilder::Deopt(const char* reason) {
933c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  ASSERT(did_then_);
934594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  builder_->Add<HDeoptimize>(reason, Deoptimizer::EAGER);
935ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  AddMergeAtJoinBlock(true);
936b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org}
937b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
938b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
939ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgvoid HGraphBuilder::IfBuilder::Return(HValue* value) {
940b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  HValue* parameter_count = builder_->graph()->GetConstantMinus1();
94171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  builder_->FinishExitCurrentBlock(
94271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org      builder_->New<HReturn>(value, parameter_count));
943ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  AddMergeAtJoinBlock(false);
944ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org}
945ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
946ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
947ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgvoid HGraphBuilder::IfBuilder::AddMergeAtJoinBlock(bool deopt) {
948ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  if (!pending_merge_block_) return;
949ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  HBasicBlock* block = builder_->current_block();
950ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  ASSERT(block == NULL || !block->IsFinished());
951ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  MergeAtJoinBlock* record =
952ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      new(builder_->zone()) MergeAtJoinBlock(block, deopt,
953ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org                                             merge_at_join_blocks_);
954ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  merge_at_join_blocks_ = record;
955ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  if (block != NULL) {
956ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    ASSERT(block->end() == NULL);
957ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    if (deopt) {
958ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      normal_merge_at_join_block_count_++;
959ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    } else {
960ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      deopt_merge_at_join_block_count_++;
961ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    }
962ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  }
963ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  builder_->set_current_block(NULL);
964ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  pending_merge_block_ = false;
965ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org}
966ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
967ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
968ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgvoid HGraphBuilder::IfBuilder::Finish() {
969ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  ASSERT(!finished_);
970ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  if (!did_then_) {
971ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    Then();
972ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  }
973ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  AddMergeAtJoinBlock(false);
974ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  if (!did_else_) {
975ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    Else();
976ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    AddMergeAtJoinBlock(false);
977ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  }
978ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  finished_ = true;
979ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org}
980ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
981ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
982ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgvoid HGraphBuilder::IfBuilder::Finish(HBasicBlock** then_continuation,
983ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org                                      HBasicBlock** else_continuation) {
984ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  Finish();
985ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
986ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  MergeAtJoinBlock* else_record = merge_at_join_blocks_;
987ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  if (else_continuation != NULL) {
988ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    *else_continuation = else_record->block_;
989ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  }
990ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  MergeAtJoinBlock* then_record = else_record->next_;
991ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  if (then_continuation != NULL) {
992ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    *then_continuation = then_record->block_;
993ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
994ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  ASSERT(then_record->next_ == NULL);
995ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
996ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
997ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
99894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgvoid HGraphBuilder::IfBuilder::End() {
999ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  if (captured_) return;
1000ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  Finish();
1001ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1002ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  int total_merged_blocks = normal_merge_at_join_block_count_ +
1003ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    deopt_merge_at_join_block_count_;
1004ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  ASSERT(total_merged_blocks >= 1);
1005ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  HBasicBlock* merge_block = total_merged_blocks == 1
1006ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      ? NULL : builder_->graph()->CreateBasicBlock();
1007ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1008ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  // Merge non-deopt blocks first to ensure environment has right size for
1009ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  // padding.
1010ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  MergeAtJoinBlock* current = merge_at_join_blocks_;
1011ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  while (current != NULL) {
1012ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    if (!current->deopt_ && current->block_ != NULL) {
1013ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      // If there is only one block that makes it through to the end of the
1014ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      // if, then just set it as the current block and continue rather then
1015ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      // creating an unnecessary merge block.
1016ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      if (total_merged_blocks == 1) {
1017ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org        builder_->set_current_block(current->block_);
1018ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org        return;
1019c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org      }
1020ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      builder_->GotoNoSimulate(current->block_, merge_block);
1021b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    }
1022ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    current = current->next_;
1023b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  }
1024ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1025ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  // Merge deopt blocks, padding when necessary.
1026ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  current = merge_at_join_blocks_;
1027ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  while (current != NULL) {
1028ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    if (current->deopt_ && current->block_ != NULL) {
1029f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      current->block_->FinishExit(
1030f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          HAbnormalExit::New(builder_->zone(), NULL),
1031f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          HSourcePosition::Unknown());
1032ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    }
1033ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    current = current->next_;
1034ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  }
1035ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  builder_->set_current_block(merge_block);
103694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org}
103794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
103894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
103994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgHGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder,
104094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org                                        HValue* context,
10412d18b3604565efb0b4d300dd899901ed866eaaaedanno@chromium.org                                        LoopBuilder::Direction direction)
104294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    : builder_(builder),
104394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      context_(context),
104494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      direction_(direction),
104594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      finished_(false) {
1046b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  header_block_ = builder->CreateLoopHeaderBlock();
104709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  body_block_ = NULL;
104809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  exit_block_ = NULL;
1049662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  exit_trampoline_block_ = NULL;
1050662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  increment_amount_ = builder_->graph()->GetConstant1();
1051662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org}
1052662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
1053662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
1054662436e7b124b3535773535c671c53db322070b5verwaest@chromium.orgHGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder,
1055662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org                                        HValue* context,
1056662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org                                        LoopBuilder::Direction direction,
1057662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org                                        HValue* increment_amount)
1058662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    : builder_(builder),
1059662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org      context_(context),
1060662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org      direction_(direction),
1061662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org      finished_(false) {
1062662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  header_block_ = builder->CreateLoopHeaderBlock();
1063662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  body_block_ = NULL;
1064662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  exit_block_ = NULL;
1065662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  exit_trampoline_block_ = NULL;
1066662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  increment_amount_ = increment_amount;
106794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org}
106894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
106994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
107009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.orgHValue* HGraphBuilder::LoopBuilder::BeginBody(
107109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    HValue* initial,
107209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    HValue* terminating,
1073dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    Token::Value token) {
107409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  HEnvironment* env = builder_->environment();
1075ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org  phi_ = header_block_->AddNewPhi(env->values()->length());
107694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  phi_->AddInput(initial);
107794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  env->Push(initial);
107871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  builder_->GotoNoSimulate(header_block_);
107909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org
108009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  HEnvironment* body_env = env->Copy();
108109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  HEnvironment* exit_env = env->Copy();
108209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  // Remove the phi from the expression stack
108309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  body_env->Pop();
1084662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  exit_env->Pop();
1085662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  body_block_ = builder_->CreateBasicBlock(body_env);
1086662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  exit_block_ = builder_->CreateBasicBlock(exit_env);
108794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
108894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  builder_->set_current_block(header_block_);
1089662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  env->Pop();
109071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  builder_->FinishCurrentBlock(builder_->New<HCompareNumericAndBranch>(
1091528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org          phi_, terminating, token, body_block_, exit_block_));
109294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
109394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  builder_->set_current_block(body_block_);
109494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  if (direction_ == kPreIncrement || direction_ == kPreDecrement) {
109594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    HValue* one = builder_->graph()->GetConstant1();
109694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    if (direction_ == kPreIncrement) {
10972e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      increment_ = HAdd::New(zone(), context_, phi_, one);
109894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    } else {
10992e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      increment_ = HSub::New(zone(), context_, phi_, one);
110094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    }
110194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    increment_->ClearFlag(HValue::kCanOverflow);
110294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    builder_->AddInstruction(increment_);
110394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    return increment_;
110494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  } else {
110594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    return phi_;
110694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  }
110794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org}
110894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
110994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
1110662436e7b124b3535773535c671c53db322070b5verwaest@chromium.orgvoid HGraphBuilder::LoopBuilder::Break() {
1111662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  if (exit_trampoline_block_ == NULL) {
1112662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    // Its the first time we saw a break.
1113662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    HEnvironment* env = exit_block_->last_environment()->Copy();
1114662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    exit_trampoline_block_ = builder_->CreateBasicBlock(env);
111571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    builder_->GotoNoSimulate(exit_block_, exit_trampoline_block_);
1116662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  }
1117662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
111871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  builder_->GotoNoSimulate(exit_trampoline_block_);
1119ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  builder_->set_current_block(NULL);
1120662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org}
1121662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
1122662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
112394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgvoid HGraphBuilder::LoopBuilder::EndBody() {
112494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  ASSERT(!finished_);
112594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
112694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  if (direction_ == kPostIncrement || direction_ == kPostDecrement) {
112794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    if (direction_ == kPostIncrement) {
1128662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org      increment_ = HAdd::New(zone(), context_, phi_, increment_amount_);
112994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    } else {
1130662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org      increment_ = HSub::New(zone(), context_, phi_, increment_amount_);
113194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    }
113294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    increment_->ClearFlag(HValue::kCanOverflow);
113394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    builder_->AddInstruction(increment_);
113494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  }
113594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
113609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  // Push the new increment value on the expression stack to merge into the phi.
113794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  builder_->environment()->Push(increment_);
1138594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HBasicBlock* last_block = builder_->current_block();
113971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  builder_->GotoNoSimulate(last_block, header_block_);
1140594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  header_block_->loop_information()->RegisterBackEdge(last_block);
114109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org
1142662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  if (exit_trampoline_block_ != NULL) {
1143662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    builder_->set_current_block(exit_trampoline_block_);
1144662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  } else {
1145662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    builder_->set_current_block(exit_block_);
1146662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  }
114794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  finished_ = true;
114894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org}
114994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
115094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
1151a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHGraph* HGraphBuilder::CreateGraph() {
1152a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  graph_ = new(zone()) HGraph(info_);
1153750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (FLAG_hydrogen_stats) isolate()->GetHStatistics()->Initialize(info_);
11541510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  CompilationPhase phase("H_Block building", info_);
1155a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  set_current_block(graph()->entry_block());
1156a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (!BuildGraph()) return NULL;
11573d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  graph()->FinalizeUniqueness();
1158a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  return graph_;
1159a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
1160a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
1161a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
1162a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) {
1163a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  ASSERT(current_block() != NULL);
1164f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  ASSERT(!FLAG_hydrogen_track_positions ||
1165f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org         !position_.IsUnknown() ||
1166f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org         !info_->IsOptimizing());
1167f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  current_block()->AddInstruction(instr, source_position());
1168ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org  if (graph()->IsInsideNoSideEffectsScope()) {
1169e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    instr->SetFlag(HValue::kHasNoObservableSideEffects);
1170e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
1171a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  return instr;
1172a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
1173a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
1174a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
117571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.orgvoid HGraphBuilder::FinishCurrentBlock(HControlInstruction* last) {
1176f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  ASSERT(!FLAG_hydrogen_track_positions ||
1177f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org         !info_->IsOptimizing() ||
1178f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org         !position_.IsUnknown());
1179f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  current_block()->Finish(last, source_position());
118071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  if (last->IsReturn() || last->IsAbnormalExit()) {
118171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    set_current_block(NULL);
118271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  }
118371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org}
118471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org
118571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org
118671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.orgvoid HGraphBuilder::FinishExitCurrentBlock(HControlInstruction* instruction) {
1187f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  ASSERT(!FLAG_hydrogen_track_positions || !info_->IsOptimizing() ||
1188f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org         !position_.IsUnknown());
1189f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  current_block()->FinishExit(instruction, source_position());
119071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  if (instruction->IsReturn() || instruction->IsAbnormalExit()) {
119171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    set_current_block(NULL);
119271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  }
119371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org}
119471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org
119571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org
1196528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid HGraphBuilder::AddIncrementCounter(StatsCounter* counter) {
1197d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  if (FLAG_native_code_counters && counter->Enabled()) {
1198d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    HValue* reference = Add<HConstant>(ExternalReference(counter));
119909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org    HValue* old_value = Add<HLoadNamedField>(
120009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org        reference, static_cast<HValue*>(NULL), HObjectAccess::ForCounter());
1201f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    HValue* new_value = AddUncasted<HAdd>(old_value, graph()->GetConstant1());
1202d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    new_value->ClearFlag(HValue::kCanOverflow);  // Ignore counter overflow
1203d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(),
120405150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org                          new_value, STORE_TO_INITIALIZED_ENTRY);
1205d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1206d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org}
1207d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1208d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1209d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgvoid HGraphBuilder::AddSimulate(BailoutId id,
1210d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                                RemovableSimulate removable) {
1211d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  ASSERT(current_block() != NULL);
1212ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org  ASSERT(!graph()->IsInsideNoSideEffectsScope());
1213f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  current_block()->AddNewSimulate(id, source_position(), removable);
1214d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org}
1215d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1216d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1217b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgHBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) {
121894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  HBasicBlock* b = graph()->CreateBasicBlock();
1219b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  b->SetInitialEnvironment(env);
122094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  return b;
122194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org}
122294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
122394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
1224b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgHBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() {
122594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  HBasicBlock* header = graph()->CreateBasicBlock();
122694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  HEnvironment* entry_env = environment()->CopyAsLoopHeader(header);
1227b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  header->SetInitialEnvironment(entry_env);
122894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  header->AttachLoopInformation();
122994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  return header;
123094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org}
123194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
123294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
12331845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgHValue* HGraphBuilder::BuildGetElementsKind(HValue* object) {
12341845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* map = Add<HLoadNamedField>(object, static_cast<HValue*>(NULL),
12351845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                     HObjectAccess::ForMap());
12361845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
12371845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* bit_field2 = Add<HLoadNamedField>(map, static_cast<HValue*>(NULL),
12381845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                            HObjectAccess::ForMapBitField2());
12391845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  return BuildDecodeField<Map::ElementsKindBits>(bit_field2);
12401845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org}
12411845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
12421845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
12431510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgHValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) {
1244906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  if (obj->type().IsHeapObject()) return obj;
12451510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return Add<HCheckHeapObject>(obj);
1246b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org}
1247b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
1248b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
1249f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid HGraphBuilder::FinishExitWithHardDeoptimization(const char* reason) {
1250594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  Add<HDeoptimize>(reason, Deoptimizer::EAGER);
1251f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  FinishExitCurrentBlock(New<HAbnormalExit>());
1252c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
1253c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
1254c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
125590dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.orgHValue* HGraphBuilder::BuildCheckString(HValue* string) {
125690dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org  if (!string->type().IsString()) {
125790dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org    ASSERT(!string->IsConstant() ||
125890dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org           !HConstant::cast(string)->HasStringValue());
125990dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org    BuildCheckHeapObject(string);
126090dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org    return Add<HCheckInstanceType>(string, HCheckInstanceType::IS_STRING);
12617ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  }
126290dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org  return string;
12637ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org}
12647ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org
12657ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org
1266c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgHValue* HGraphBuilder::BuildWrapReceiver(HValue* object, HValue* function) {
1267c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if (object->type().IsJSObject()) return object;
126857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  if (function->IsConstant() &&
126957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      HConstant::cast(function)->handle(isolate())->IsJSFunction()) {
127057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    Handle<JSFunction> f = Handle<JSFunction>::cast(
127157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org        HConstant::cast(function)->handle(isolate()));
127257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    SharedFunctionInfo* shared = f->shared();
1273486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    if (shared->strict_mode() == STRICT || shared->native()) return object;
127457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  }
1275c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  return Add<HWrapReceiver>(object, function);
1276c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
1277c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
1278c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
1279f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgHValue* HGraphBuilder::BuildCheckForCapacityGrow(
1280f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    HValue* object,
1281f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    HValue* elements,
1282f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    ElementsKind kind,
1283f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    HValue* length,
1284f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    HValue* key,
1285f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    bool is_js_array,
1286f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    PropertyAccessType access_type) {
12872d18b3604565efb0b4d300dd899901ed866eaaaedanno@chromium.org  IfBuilder length_checker(this);
12887bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
1289169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  Token::Value token = IsHoleyElementsKind(kind) ? Token::GTE : Token::EQ;
1290169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  length_checker.If<HCompareNumericAndBranch>(key, length, token);
1291169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1292b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  length_checker.Then();
12937bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
1294c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  HValue* current_capacity = AddLoadFixedArrayLength(elements);
12957bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
12962d18b3604565efb0b4d300dd899901ed866eaaaedanno@chromium.org  IfBuilder capacity_checker(this);
12977bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
1298169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  capacity_checker.If<HCompareNumericAndBranch>(key, current_capacity,
1299169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                                                Token::GTE);
1300b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  capacity_checker.Then();
13017bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
1302d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HValue* max_gap = Add<HConstant>(static_cast<int32_t>(JSObject::kMaxGap));
13037ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  HValue* max_capacity = AddUncasted<HAdd>(current_capacity, max_gap);
1304a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org
1305a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  Add<HBoundsCheck>(key, max_capacity);
1306c22f2d813ad21e25e8df5d4a371fd63f582e4262danno@chromium.org
1307d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HValue* new_capacity = BuildNewElementsCapacity(key);
13087bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  HValue* new_elements = BuildGrowElementsCapacity(object, elements,
1309bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org                                                   kind, kind, length,
13102d18b3604565efb0b4d300dd899901ed866eaaaedanno@chromium.org                                                   new_capacity);
13117bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
13127bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  environment()->Push(new_elements);
1313b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  capacity_checker.Else();
13147bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
13157bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  environment()->Push(elements);
13167bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  capacity_checker.End();
13177bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
13187bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  if (is_js_array) {
1319db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org    HValue* new_length = AddUncasted<HAdd>(key, graph_->GetConstant1());
13207bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org    new_length->ClearFlag(HValue::kCanOverflow);
13217bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
1322d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(kind),
13230a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                          new_length);
13247bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  }
13257bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
1326f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (access_type == STORE && kind == FAST_SMI_ELEMENTS) {
132771ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org    HValue* checked_elements = environment()->Top();
132871ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org
132971ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org    // Write zero to ensure that the new element is initialized with some smi.
13300a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    Add<HStoreKeyed>(checked_elements, key, graph()->GetConstant0(), kind);
133171ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org  }
133271ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org
1333b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  length_checker.Else();
13341510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Add<HBoundsCheck>(key, length);
13357bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
1336169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  environment()->Push(elements);
13377bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  length_checker.End();
13387bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
13397bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  return environment()->Pop();
13407bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org}
13417bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
13427bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
13437bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgHValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object,
13447bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                                HValue* elements,
13457bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                                ElementsKind kind,
13467bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                                HValue* length) {
1347e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  Factory* factory = isolate()->factory();
13487bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
13492d18b3604565efb0b4d300dd899901ed866eaaaedanno@chromium.org  IfBuilder cow_checker(this);
13507bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
1351052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org  cow_checker.If<HCompareMap>(elements, factory->fixed_cow_array_map());
1352b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  cow_checker.Then();
13537bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
1354c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  HValue* capacity = AddLoadFixedArrayLength(elements);
13557bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
1356bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  HValue* new_elements = BuildGrowElementsCapacity(object, elements, kind,
1357b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org                                                   kind, length, capacity);
13587bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
13597bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  environment()->Push(new_elements);
13607bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
1361b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  cow_checker.Else();
13627bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
13637bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  environment()->Push(elements);
13647bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
13657bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  cow_checker.End();
13667bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
13677bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  return environment()->Pop();
13687bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org}
13697bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
13707bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
1371ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgvoid HGraphBuilder::BuildTransitionElementsKind(HValue* object,
1372ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                                HValue* map,
1373ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                                ElementsKind from_kind,
1374ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                                ElementsKind to_kind,
1375ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                                bool is_jsarray) {
1376ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  ASSERT(!IsFastHoleyElementsKind(from_kind) ||
1377ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org         IsFastHoleyElementsKind(to_kind));
1378ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1379ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (AllocationSite::GetMode(from_kind, to_kind) == TRACK_ALLOCATION_SITE) {
1380ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Add<HTrapAllocationMemento>(object);
1381ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  }
1382ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1383ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (!IsSimpleMapChangeTransition(from_kind, to_kind)) {
1384ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org    HInstruction* elements = AddLoadElements(object);
1385ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1386ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    HInstruction* empty_fixed_array = Add<HConstant>(
1387d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        isolate()->factory()->empty_fixed_array());
1388ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1389ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    IfBuilder if_builder(this);
1390ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1391ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    if_builder.IfNot<HCompareObjectEqAndBranch>(elements, empty_fixed_array);
1392ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1393ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    if_builder.Then();
1394ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1395ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    HInstruction* elements_length = AddLoadFixedArrayLength(elements);
1396ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1397ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    HInstruction* array_length = is_jsarray
139809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org        ? Add<HLoadNamedField>(object, static_cast<HValue*>(NULL),
139909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org                               HObjectAccess::ForArrayLength(from_kind))
1400ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        : elements_length;
1401ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1402ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    BuildGrowElementsCapacity(object, elements, from_kind, to_kind,
1403ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                              array_length, elements_length);
1404ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1405ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    if_builder.End();
1406ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  }
1407ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
14080a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map);
1409ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org}
1410ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1411ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
14121845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgvoid HGraphBuilder::BuildJSObjectCheck(HValue* receiver,
14131845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                       int bit_field_mask) {
14141845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  // Check that the object isn't a smi.
14151845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  Add<HCheckHeapObject>(receiver);
14161845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
14171845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  // Get the map of the receiver.
14181845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* map = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL),
14191845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                     HObjectAccess::ForMap());
14201845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
14211845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  // Check the instance type and if an access check is needed, this can be
14221845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  // done with a single load, since both bytes are adjacent in the map.
14231845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HObjectAccess access(HObjectAccess::ForMapInstanceTypeAndBitField());
14241845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* instance_type_and_bit_field =
14251845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      Add<HLoadNamedField>(map, static_cast<HValue*>(NULL), access);
14261845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
14271845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* mask = Add<HConstant>(0x00FF | (bit_field_mask << 8));
14281845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* and_result = AddUncasted<HBitwise>(Token::BIT_AND,
14291845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                             instance_type_and_bit_field,
14301845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                             mask);
14311845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* sub_result = AddUncasted<HSub>(and_result,
14321845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                         Add<HConstant>(JS_OBJECT_TYPE));
14331845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  Add<HBoundsCheck>(sub_result, Add<HConstant>(0x100 - JS_OBJECT_TYPE));
14341845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org}
14351845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
14361845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
14371845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgvoid HGraphBuilder::BuildKeyedIndexCheck(HValue* key,
14381845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                         HIfContinuation* join_continuation) {
14391845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  // The sometimes unintuitively backward ordering of the ifs below is
14401845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  // convoluted, but necessary.  All of the paths must guarantee that the
14411845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  // if-true of the continuation returns a smi element index and the if-false of
14421845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  // the continuation returns either a symbol or a unique string key. All other
14431845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  // object types cause a deopt to fall back to the runtime.
14441845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
14451845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  IfBuilder key_smi_if(this);
14461845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  key_smi_if.If<HIsSmiAndBranch>(key);
14471845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  key_smi_if.Then();
14481845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  {
14491845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    Push(key);  // Nothing to do, just continue to true of continuation.
14501845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  }
14511845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  key_smi_if.Else();
14521845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  {
14531845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    HValue* map = Add<HLoadNamedField>(key, static_cast<HValue*>(NULL),
14541845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                       HObjectAccess::ForMap());
14551845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    HValue* instance_type =
14561845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        Add<HLoadNamedField>(map, static_cast<HValue*>(NULL),
14571845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                             HObjectAccess::ForMapInstanceType());
14581845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
14591845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    // Non-unique string, check for a string with a hash code that is actually
14601845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    // an index.
14611845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    STATIC_ASSERT(LAST_UNIQUE_NAME_TYPE == FIRST_NONSTRING_TYPE);
14621845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    IfBuilder not_string_or_name_if(this);
14631845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    not_string_or_name_if.If<HCompareNumericAndBranch>(
14641845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        instance_type,
14651845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        Add<HConstant>(LAST_UNIQUE_NAME_TYPE),
14661845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        Token::GT);
14671845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
14681845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    not_string_or_name_if.Then();
14691845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    {
14701845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      // Non-smi, non-Name, non-String: Try to convert to smi in case of
14711845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      // HeapNumber.
14721845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      // TODO(danno): This could call some variant of ToString
14731845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      Push(AddUncasted<HForceRepresentation>(key, Representation::Smi()));
14741845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    }
14751845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    not_string_or_name_if.Else();
14761845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    {
14771845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      // String or Name: check explicitly for Name, they can short-circuit
14781845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      // directly to unique non-index key path.
14791845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      IfBuilder not_symbol_if(this);
14801845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      not_symbol_if.If<HCompareNumericAndBranch>(
14811845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org          instance_type,
14821845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org          Add<HConstant>(SYMBOL_TYPE),
14831845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org          Token::NE);
14841845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
14851845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      not_symbol_if.Then();
14861845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      {
14871845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        // String: check whether the String is a String of an index. If it is,
14881845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        // extract the index value from the hash.
14891845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        HValue* hash =
14901845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org            Add<HLoadNamedField>(key, static_cast<HValue*>(NULL),
14911845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                 HObjectAccess::ForNameHashField());
14921845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        HValue* not_index_mask = Add<HConstant>(static_cast<int>(
14931845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org            String::kContainsCachedArrayIndexMask));
14941845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
14951845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        HValue* not_index_test = AddUncasted<HBitwise>(
14961845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org            Token::BIT_AND, hash, not_index_mask);
14971845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
14981845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        IfBuilder string_index_if(this);
14991845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        string_index_if.If<HCompareNumericAndBranch>(not_index_test,
15001845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                                     graph()->GetConstant0(),
15011845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                                     Token::EQ);
15021845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        string_index_if.Then();
15031845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        {
15041845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org          // String with index in hash: extract string and merge to index path.
15051845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org          Push(BuildDecodeField<String::ArrayIndexValueBits>(hash));
15061845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        }
15071845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        string_index_if.Else();
15081845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        {
15091845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org          // Key is a non-index String, check for uniqueness/internalization. If
15101845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org          // it's not, deopt.
15111845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org          HValue* not_internalized_bit = AddUncasted<HBitwise>(
15121845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org              Token::BIT_AND,
15131845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org              instance_type,
15141845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org              Add<HConstant>(static_cast<int>(kIsNotInternalizedMask)));
15151845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org          DeoptimizeIf<HCompareNumericAndBranch>(
15161845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org              not_internalized_bit,
15171845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org              graph()->GetConstant0(),
15181845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org              Token::NE,
15191845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org              "BuildKeyedIndexCheck: string isn't internalized");
15201845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org          // Key guaranteed to be a unqiue string
15211845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org          Push(key);
15221845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        }
15231845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        string_index_if.JoinContinuation(join_continuation);
15241845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      }
15251845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      not_symbol_if.Else();
15261845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      {
15271845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        Push(key);  // Key is symbol
15281845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      }
15291845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      not_symbol_if.JoinContinuation(join_continuation);
15301845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    }
15311845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    not_string_or_name_if.JoinContinuation(join_continuation);
15321845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  }
15331845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  key_smi_if.JoinContinuation(join_continuation);
15341845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org}
15351845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
15361845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
15371845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgvoid HGraphBuilder::BuildNonGlobalObjectCheck(HValue* receiver) {
15381845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  // Get the the instance type of the receiver, and make sure that it is
15391845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  // not one of the global object types.
15401845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* map = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL),
15411845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                     HObjectAccess::ForMap());
15421845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* instance_type =
15431845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    Add<HLoadNamedField>(map, static_cast<HValue*>(NULL),
15441845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                         HObjectAccess::ForMapInstanceType());
15451845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  STATIC_ASSERT(JS_BUILTINS_OBJECT_TYPE == JS_GLOBAL_OBJECT_TYPE + 1);
15461845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* min_global_type = Add<HConstant>(JS_GLOBAL_OBJECT_TYPE);
15471845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* max_global_type = Add<HConstant>(JS_BUILTINS_OBJECT_TYPE);
15481845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
15491845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  IfBuilder if_global_object(this);
15501845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  if_global_object.If<HCompareNumericAndBranch>(instance_type,
15511845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                                max_global_type,
15521845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                                Token::LTE);
15531845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  if_global_object.And();
15541845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  if_global_object.If<HCompareNumericAndBranch>(instance_type,
15551845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                                min_global_type,
15561845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                                Token::GTE);
15571845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  if_global_object.ThenDeopt("receiver was a global object");
15581845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  if_global_object.End();
15591845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org}
15601845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
15611845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
15621845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgvoid HGraphBuilder::BuildTestForDictionaryProperties(
15631845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    HValue* object,
15641845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    HIfContinuation* continuation) {
15651845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* properties = Add<HLoadNamedField>(
15661845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      object, static_cast<HValue*>(NULL),
15671845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      HObjectAccess::ForPropertiesPointer());
15681845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* properties_map =
15691845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      Add<HLoadNamedField>(properties, static_cast<HValue*>(NULL),
15701845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                           HObjectAccess::ForMap());
15711845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* hash_map = Add<HLoadRoot>(Heap::kHashTableMapRootIndex);
15721845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  IfBuilder builder(this);
15731845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  builder.If<HCompareObjectEqAndBranch>(properties_map, hash_map);
15741845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  builder.CaptureContinuation(continuation);
15751845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org}
15761845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
15771845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
15781845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgHValue* HGraphBuilder::BuildKeyedLookupCacheHash(HValue* object,
15791845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                                 HValue* key) {
15801845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  // Load the map of the receiver, compute the keyed lookup cache hash
15811845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  // based on 32 bits of the map pointer and the string hash.
15821845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* object_map =
15831845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      Add<HLoadNamedField>(object, static_cast<HValue*>(NULL),
15841845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                           HObjectAccess::ForMapAsInteger32());
15851845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* shifted_map = AddUncasted<HShr>(
15861845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      object_map, Add<HConstant>(KeyedLookupCache::kMapHashShift));
15871845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* string_hash =
15881845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      Add<HLoadNamedField>(key, static_cast<HValue*>(NULL),
15891845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                           HObjectAccess::ForStringHashField());
15901845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* shifted_hash = AddUncasted<HShr>(
15911845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      string_hash, Add<HConstant>(String::kHashShift));
15921845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* xor_result = AddUncasted<HBitwise>(Token::BIT_XOR, shifted_map,
15931845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                             shifted_hash);
15941845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  int mask = (KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask);
15951845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  return AddUncasted<HBitwise>(Token::BIT_AND, xor_result,
15961845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                               Add<HConstant>(mask));
15971845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org}
15981845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
15991845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
1600ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgHValue* HGraphBuilder::BuildUncheckedDictionaryElementLoadHelper(
1601ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    HValue* elements,
1602ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    HValue* key,
1603ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    HValue* hash,
1604ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    HValue* mask,
1605ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    int current_probe) {
1606ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  if (current_probe == kNumberDictionaryProbes) {
1607ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    return NULL;
1608ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  }
1609ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1610ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  int32_t offset = SeededNumberDictionary::GetProbeOffset(current_probe);
1611ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  HValue* raw_index = (current_probe == 0)
1612ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      ? hash
16137ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org      : AddUncasted<HAdd>(hash, Add<HConstant>(offset));
16147ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  raw_index = AddUncasted<HBitwise>(Token::BIT_AND, raw_index, mask);
1615ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  int32_t entry_size = SeededNumberDictionary::kEntrySize;
16167ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  raw_index = AddUncasted<HMul>(raw_index, Add<HConstant>(entry_size));
1617ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  raw_index->ClearFlag(HValue::kCanOverflow);
1618ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1619ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  int32_t base_offset = SeededNumberDictionary::kElementsStartIndex;
16207ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  HValue* key_index = AddUncasted<HAdd>(raw_index, Add<HConstant>(base_offset));
1621ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  key_index->ClearFlag(HValue::kCanOverflow);
1622ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1623ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  HValue* candidate_key = Add<HLoadKeyed>(elements, key_index,
1624ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org                                          static_cast<HValue*>(NULL),
1625f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                          FAST_ELEMENTS);
1626ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1627ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  IfBuilder key_compare(this);
1628ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  key_compare.IfNot<HCompareObjectEqAndBranch>(key, candidate_key);
1629ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  key_compare.Then();
1630ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  {
1631ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    // Key at the current probe doesn't match, try at the next probe.
1632ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    HValue* result = BuildUncheckedDictionaryElementLoadHelper(
1633ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org        elements, key, hash, mask, current_probe + 1);
1634ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    if (result == NULL) {
1635ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      key_compare.Deopt("probes exhausted in keyed load dictionary lookup");
1636ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      result = graph()->GetConstantUndefined();
1637ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    } else {
1638ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      Push(result);
1639ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    }
1640ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  }
1641ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  key_compare.Else();
1642ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  {
1643ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    // Key at current probe matches. Details must be zero, otherwise the
1644ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    // dictionary element requires special handling.
16457ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org    HValue* details_index = AddUncasted<HAdd>(
16467ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org        raw_index, Add<HConstant>(base_offset + 2));
1647ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    details_index->ClearFlag(HValue::kCanOverflow);
1648ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1649ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    HValue* details = Add<HLoadKeyed>(elements, details_index,
1650ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org                                      static_cast<HValue*>(NULL),
1651f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                      FAST_ELEMENTS);
1652ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    IfBuilder details_compare(this);
1653ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    details_compare.If<HCompareNumericAndBranch>(details,
1654ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org                                                 graph()->GetConstant0(),
1655ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org                                                 Token::NE);
1656ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    details_compare.ThenDeopt("keyed load dictionary element not fast case");
1657ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1658ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    details_compare.Else();
1659ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    {
1660ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      // Key matches and details are zero --> fast case. Load and return the
1661ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      // value.
16627ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org      HValue* result_index = AddUncasted<HAdd>(
16637ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org          raw_index, Add<HConstant>(base_offset + 1));
1664ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      result_index->ClearFlag(HValue::kCanOverflow);
1665ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1666ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      Push(Add<HLoadKeyed>(elements, result_index,
1667ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org                           static_cast<HValue*>(NULL),
1668ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org                           FAST_ELEMENTS));
1669ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    }
1670ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    details_compare.End();
1671ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  }
1672ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  key_compare.End();
1673ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1674ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  return Pop();
1675ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org}
1676ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1677ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1678ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgHValue* HGraphBuilder::BuildElementIndexHash(HValue* index) {
1679ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  int32_t seed_value = static_cast<uint32_t>(isolate()->heap()->HashSeed());
1680ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  HValue* seed = Add<HConstant>(seed_value);
16817ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  HValue* hash = AddUncasted<HBitwise>(Token::BIT_XOR, index, seed);
1682ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1683ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  // hash = ~hash + (hash << 15);
16847ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  HValue* shifted_hash = AddUncasted<HShl>(hash, Add<HConstant>(15));
16857ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  HValue* not_hash = AddUncasted<HBitwise>(Token::BIT_XOR, hash,
16867ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org                                           graph()->GetConstantMinus1());
16877ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  hash = AddUncasted<HAdd>(shifted_hash, not_hash);
1688ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1689ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  // hash = hash ^ (hash >> 12);
16907ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(12));
16917ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  hash = AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash);
1692ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1693ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  // hash = hash + (hash << 2);
16947ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  shifted_hash = AddUncasted<HShl>(hash, Add<HConstant>(2));
16957ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  hash = AddUncasted<HAdd>(hash, shifted_hash);
1696ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1697ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  // hash = hash ^ (hash >> 4);
16987ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(4));
16997ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  hash = AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash);
1700ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1701ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  // hash = hash * 2057;
17027ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  hash = AddUncasted<HMul>(hash, Add<HConstant>(2057));
1703ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  hash->ClearFlag(HValue::kCanOverflow);
1704ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1705ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  // hash = hash ^ (hash >> 16);
17067ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(16));
17077ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  return AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash);
1708ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org}
1709ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1710ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1711ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgHValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad(HValue* receiver,
17121845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                                           HValue* elements,
17131845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                                           HValue* key,
17141845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                                           HValue* hash) {
1715ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  HValue* capacity = Add<HLoadKeyed>(
1716ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      elements,
1717ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      Add<HConstant>(NameDictionary::kCapacityIndex),
1718ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      static_cast<HValue*>(NULL),
1719f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      FAST_ELEMENTS);
1720ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1721f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  HValue* mask = AddUncasted<HSub>(capacity, graph()->GetConstant1());
1722ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  mask->ChangeRepresentation(Representation::Integer32());
1723ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  mask->ClearFlag(HValue::kCanOverflow);
1724ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1725ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  return BuildUncheckedDictionaryElementLoadHelper(elements, key,
1726ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org                                                   hash, mask, 0);
1727ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org}
1728ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1729ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
173009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.orgHValue* HGraphBuilder::BuildRegExpConstructResult(HValue* length,
173109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org                                                  HValue* index,
173209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org                                                  HValue* input) {
173309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  NoObservableSideEffectsScope scope(this);
173438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HConstant* max_length = Add<HConstant>(JSObject::kInitialMaxFastElementArray);
173538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  Add<HBoundsCheck>(length, max_length);
173609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
173738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  // Generate size calculation code here in order to make it dominate
173838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  // the JSRegExpResult allocation.
173938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  ElementsKind elements_kind = FAST_ELEMENTS;
174038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HValue* size = BuildCalculateElementsSize(elements_kind, length);
174109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
174209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  // Allocate the JSRegExpResult and the FixedArray in one step.
174309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  HValue* result = Add<HAllocate>(
174438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      Add<HConstant>(JSRegExpResult::kSize), HType::JSArray(),
174538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      NOT_TENURED, JS_ARRAY_TYPE);
174609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
174709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  // Initialize the JSRegExpResult header.
174809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  HValue* global_object = Add<HLoadNamedField>(
174909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      context(), static_cast<HValue*>(NULL),
175009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
175109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  HValue* native_context = Add<HLoadNamedField>(
175209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      global_object, static_cast<HValue*>(NULL),
175309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      HObjectAccess::ForGlobalObjectNativeContext());
17546a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  Add<HStoreNamedField>(
17556a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      result, HObjectAccess::ForMap(),
17566a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      Add<HLoadNamedField>(
175709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org          native_context, static_cast<HValue*>(NULL),
175809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org          HObjectAccess::ForContextSlot(Context::REGEXP_RESULT_MAP_INDEX)));
175938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HConstant* empty_fixed_array =
176038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      Add<HConstant>(isolate()->factory()->empty_fixed_array());
176109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  Add<HStoreNamedField>(
176209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      result, HObjectAccess::ForJSArrayOffset(JSArray::kPropertiesOffset),
176338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      empty_fixed_array);
176409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  Add<HStoreNamedField>(
176509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      result, HObjectAccess::ForJSArrayOffset(JSArray::kElementsOffset),
176638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      empty_fixed_array);
176709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  Add<HStoreNamedField>(
17680a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      result, HObjectAccess::ForJSArrayOffset(JSArray::kLengthOffset), length);
176909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
177009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  // Initialize the additional fields.
177109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  Add<HStoreNamedField>(
177209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      result, HObjectAccess::ForJSArrayOffset(JSRegExpResult::kIndexOffset),
17730a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      index);
177409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  Add<HStoreNamedField>(
177509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      result, HObjectAccess::ForJSArrayOffset(JSRegExpResult::kInputOffset),
17760a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      input);
177709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
177838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  // Allocate and initialize the elements header.
177938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HAllocate* elements = BuildAllocateElements(elements_kind, size);
178038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  BuildInitializeElementsHeader(elements, elements_kind, length);
178138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
178238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HConstant* size_in_bytes_upper_bound = EstablishElementsAllocationSize(
178338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      elements_kind, max_length->Integer32Value());
178438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  elements->set_size_upper_bound(size_in_bytes_upper_bound);
178538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
178638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  Add<HStoreNamedField>(
178738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      result, HObjectAccess::ForJSArrayOffset(JSArray::kElementsOffset),
178838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      elements);
178909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
179009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  // Initialize the elements contents with undefined.
179138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  BuildFillElementsWithValue(
179238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      elements, elements_kind, graph()->GetConstant0(), length,
179338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      graph()->GetConstantUndefined());
179409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
179509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  return result;
179609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org}
179709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
179809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
17996d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.orgHValue* HGraphBuilder::BuildNumberToString(HValue* object, Type* type) {
1800e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org  NoObservableSideEffectsScope scope(this);
1801e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org
18027ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  // Convert constant numbers at compile time.
18037ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  if (object->IsConstant() && HConstant::cast(object)->HasNumberValue()) {
18047ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org    Handle<Object> number = HConstant::cast(object)->handle(isolate());
18057ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org    Handle<String> result = isolate()->factory()->NumberToString(number);
18067ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org    return Add<HConstant>(result);
18077ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  }
18087ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org
18093d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  // Create a joinable continuation.
18103d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  HIfContinuation found(graph()->CreateBasicBlock(),
18113d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org                        graph()->CreateBasicBlock());
18123d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org
18133d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  // Load the number string cache.
18143d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  HValue* number_string_cache =
18153d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org      Add<HLoadRoot>(Heap::kNumberStringCacheRootIndex);
18163d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org
1817e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org  // Make the hash mask from the length of the number string cache. It
18183d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  // contains two elements (number and string) for each cache entry.
18193d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  HValue* mask = AddLoadFixedArrayLength(number_string_cache);
18203d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  mask->set_type(HType::Smi());
1821f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  mask = AddUncasted<HSar>(mask, graph()->GetConstant1());
1822f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  mask = AddUncasted<HSub>(mask, graph()->GetConstant1());
18233d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org
18243d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  // Check whether object is a smi.
18253d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  IfBuilder if_objectissmi(this);
18263d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  if_objectissmi.If<HIsSmiAndBranch>(object);
18273d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  if_objectissmi.Then();
18283d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  {
18293d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org    // Compute hash for smi similar to smi_get_hash().
18307ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org    HValue* hash = AddUncasted<HBitwise>(Token::BIT_AND, object, mask);
18313d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org
18323d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org    // Load the key.
18337ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org    HValue* key_index = AddUncasted<HShl>(hash, graph()->GetConstant1());
1834b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    HValue* key = Add<HLoadKeyed>(number_string_cache, key_index,
1835b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                                  static_cast<HValue*>(NULL),
1836b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                                  FAST_ELEMENTS, ALLOW_RETURN_HOLE);
18373d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org
18383d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org    // Check if object == key.
18393d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org    IfBuilder if_objectiskey(this);
1840e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org    if_objectiskey.If<HCompareObjectEqAndBranch>(object, key);
18413d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org    if_objectiskey.Then();
18423d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org    {
18433d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org      // Make the key_index available.
18443d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org      Push(key_index);
18453d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org    }
18463d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org    if_objectiskey.JoinContinuation(&found);
18473d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  }
18483d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  if_objectissmi.Else();
18493d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  {
18504452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org    if (type->Is(Type::SignedSmall())) {
1851cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org      if_objectissmi.Deopt("Expected smi");
1852e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org    } else {
1853e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      // Check if the object is a heap number.
1854e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      IfBuilder if_objectisnumber(this);
185509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      HValue* objectisnumber = if_objectisnumber.If<HCompareMap>(
1856052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org          object, isolate()->factory()->heap_number_map());
1857e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      if_objectisnumber.Then();
18583d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org      {
1859e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org        // Compute hash for heap number similar to double_get_hash().
1860e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org        HValue* low = Add<HLoadNamedField>(
186109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org            object, objectisnumber,
186209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org            HObjectAccess::ForHeapNumberValueLowestBits());
1863e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org        HValue* high = Add<HLoadNamedField>(
186409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org            object, objectisnumber,
186509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org            HObjectAccess::ForHeapNumberValueHighestBits());
18667ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org        HValue* hash = AddUncasted<HBitwise>(Token::BIT_XOR, low, high);
18677ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org        hash = AddUncasted<HBitwise>(Token::BIT_AND, hash, mask);
1868e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org
1869e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org        // Load the key.
18707ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org        HValue* key_index = AddUncasted<HShl>(hash, graph()->GetConstant1());
1871e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org        HValue* key = Add<HLoadKeyed>(number_string_cache, key_index,
1872e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org                                      static_cast<HValue*>(NULL),
1873e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org                                      FAST_ELEMENTS, ALLOW_RETURN_HOLE);
1874e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org
1875eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org        // Check if the key is a heap number and compare it with the object.
1876e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org        IfBuilder if_keyisnotsmi(this);
187709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org        HValue* keyisnotsmi = if_keyisnotsmi.IfNot<HIsSmiAndBranch>(key);
1878e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org        if_keyisnotsmi.Then();
18793d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org        {
1880eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org          IfBuilder if_keyisheapnumber(this);
1881eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org          if_keyisheapnumber.If<HCompareMap>(
1882eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org              key, isolate()->factory()->heap_number_map());
1883eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org          if_keyisheapnumber.Then();
1884e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org          {
1885eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org            // Check if values of key and object match.
1886eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org            IfBuilder if_keyeqobject(this);
1887eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org            if_keyeqobject.If<HCompareNumericAndBranch>(
1888eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org                Add<HLoadNamedField>(key, keyisnotsmi,
1889eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org                                     HObjectAccess::ForHeapNumberValue()),
1890eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org                Add<HLoadNamedField>(object, objectisnumber,
1891eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org                                     HObjectAccess::ForHeapNumberValue()),
1892eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org                Token::EQ);
1893eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org            if_keyeqobject.Then();
1894eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org            {
1895eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org              // Make the key_index available.
1896eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org              Push(key_index);
1897eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org            }
1898eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org            if_keyeqobject.JoinContinuation(&found);
1899e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org          }
1900eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org          if_keyisheapnumber.JoinContinuation(&found);
1901e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org        }
1902e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org        if_keyisnotsmi.JoinContinuation(&found);
1903e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      }
1904e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      if_objectisnumber.Else();
1905e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      {
1906e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org        if (type->Is(Type::Number())) {
1907e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org          if_objectisnumber.Deopt("Expected heap number");
19083d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org        }
19093d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org      }
1910e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      if_objectisnumber.JoinContinuation(&found);
19113d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org    }
19123d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  }
1913e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org  if_objectissmi.JoinContinuation(&found);
19143d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org
19153d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  // Check for cache hit.
19163d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  IfBuilder if_found(this, &found);
19173d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  if_found.Then();
1918e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org  {
1919e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org    // Count number to string operation in native code.
1920e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org    AddIncrementCounter(isolate()->counters()->number_to_string_native());
19213d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org
1922e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org    // Load the value in case of cache hit.
1923e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org    HValue* key_index = Pop();
19247ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org    HValue* value_index = AddUncasted<HAdd>(key_index, graph()->GetConstant1());
1925e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org    Push(Add<HLoadKeyed>(number_string_cache, value_index,
1926e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org                         static_cast<HValue*>(NULL),
1927e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org                         FAST_ELEMENTS, ALLOW_RETURN_HOLE));
1928e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org  }
19293d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  if_found.Else();
1930e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org  {
1931e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org    // Cache miss, fallback to runtime.
19328d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    Add<HPushArguments>(object);
1933e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org    Push(Add<HCallRuntime>(
1934e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org            isolate()->factory()->empty_string(),
1935895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org            Runtime::FunctionForId(Runtime::kHiddenNumberToStringSkipCache),
1936e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org            1));
1937e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org  }
19383d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  if_found.End();
19393d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org
19403d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  return Pop();
19413d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org}
19423d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org
19433d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org
19440f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.orgHAllocate* HGraphBuilder::BuildAllocate(
19450f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    HValue* object_size,
19460f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    HType type,
19470f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    InstanceType instance_type,
19480f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    HAllocationMode allocation_mode) {
19490f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // Compute the effective allocation size.
19500f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HValue* size = object_size;
19510f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  if (allocation_mode.CreateAllocationMementos()) {
19520f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    size = AddUncasted<HAdd>(size, Add<HConstant>(AllocationMemento::kSize));
19530cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    size->ClearFlag(HValue::kCanOverflow);
19540cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  }
19550f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
19560f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // Perform the actual allocation.
19570f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HAllocate* object = Add<HAllocate>(
19580f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      size, type, allocation_mode.GetPretenureMode(),
19590f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      instance_type, allocation_mode.feedback_site());
19600f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
19610f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // Setup the allocation memento.
19620f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  if (allocation_mode.CreateAllocationMementos()) {
19630f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    BuildCreateAllocationMemento(
19640f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org        object, object_size, allocation_mode.current_site());
19650f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  }
19660f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
19670f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  return object;
19680f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org}
19690f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
19700f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
19710f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.orgHValue* HGraphBuilder::BuildAddStringLengths(HValue* left_length,
19720f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                                             HValue* right_length) {
197386b1631344aedfc4be5dcd5237e28d0b28e5974emachenbach@chromium.org  // Compute the combined string length and check against max string length.
19740f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HValue* length = AddUncasted<HAdd>(left_length, right_length);
19754edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  // Check that length <= kMaxLength <=> length < MaxLength + 1.
19764edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  HValue* max_length = Add<HConstant>(String::kMaxLength + 1);
19777010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  Add<HBoundsCheck>(length, max_length);
19780f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  return length;
19790f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org}
19800f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
19810f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
19820f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.orgHValue* HGraphBuilder::BuildCreateConsString(
19830f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    HValue* length,
19840f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    HValue* left,
19850f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    HValue* right,
19860f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    HAllocationMode allocation_mode) {
19870f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // Determine the string instance types.
19880f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HInstruction* left_instance_type = AddLoadStringInstanceType(left);
19890f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HInstruction* right_instance_type = AddLoadStringInstanceType(right);
19900f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
19910f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // Allocate the cons string object. HAllocate does not care whether we
19920f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // pass CONS_STRING_TYPE or CONS_ASCII_STRING_TYPE here, so we just use
19930f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // CONS_STRING_TYPE here. Below we decide whether the cons string is
19940f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // one-byte or two-byte and set the appropriate map.
19950f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  ASSERT(HAllocate::CompatibleInstanceTypes(CONS_STRING_TYPE,
19960f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                                            CONS_ASCII_STRING_TYPE));
19970f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HAllocate* result = BuildAllocate(Add<HConstant>(ConsString::kSize),
19980f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                                    HType::String(), CONS_STRING_TYPE,
19990f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                                    allocation_mode);
20000f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
20010f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // Compute intersection and difference of instance types.
20020f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HValue* anded_instance_types = AddUncasted<HBitwise>(
20030f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      Token::BIT_AND, left_instance_type, right_instance_type);
20040f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HValue* xored_instance_types = AddUncasted<HBitwise>(
20050f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      Token::BIT_XOR, left_instance_type, right_instance_type);
20060f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
20070f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // We create a one-byte cons string if
20080f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // 1. both strings are one-byte, or
20090f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // 2. at least one of the strings is two-byte, but happens to contain only
20100f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  //    one-byte characters.
20110f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // To do this, we check
20120f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // 1. if both strings are one-byte, or if the one-byte data hint is set in
20130f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  //    both strings, or
20140f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // 2. if one of the strings has the one-byte data hint set and the other
20150f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  //    string is one-byte.
20160f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  IfBuilder if_onebyte(this);
20170f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  STATIC_ASSERT(kOneByteStringTag != 0);
20180f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  STATIC_ASSERT(kOneByteDataHintMask != 0);
20190f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  if_onebyte.If<HCompareNumericAndBranch>(
20200f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      AddUncasted<HBitwise>(
20210f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org          Token::BIT_AND, anded_instance_types,
20220f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org          Add<HConstant>(static_cast<int32_t>(
20230f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                  kStringEncodingMask | kOneByteDataHintMask))),
20240f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      graph()->GetConstant0(), Token::NE);
20250f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  if_onebyte.Or();
20260f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  STATIC_ASSERT(kOneByteStringTag != 0 &&
20270f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                kOneByteDataHintTag != 0 &&
20280f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                kOneByteDataHintTag != kOneByteStringTag);
20290f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  if_onebyte.If<HCompareNumericAndBranch>(
20300f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      AddUncasted<HBitwise>(
20310f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org          Token::BIT_AND, xored_instance_types,
20320f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org          Add<HConstant>(static_cast<int32_t>(
20330f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                  kOneByteStringTag | kOneByteDataHintTag))),
20340f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      Add<HConstant>(static_cast<int32_t>(
20350f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org              kOneByteStringTag | kOneByteDataHintTag)), Token::EQ);
20360f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  if_onebyte.Then();
20370f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  {
20380f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    // We can safely skip the write barrier for storing the map here.
20396a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    Add<HStoreNamedField>(
20406a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org        result, HObjectAccess::ForMap(),
20416a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org        Add<HConstant>(isolate()->factory()->cons_ascii_string_map()));
20420f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  }
20430f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  if_onebyte.Else();
20440f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  {
20450f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    // We can safely skip the write barrier for storing the map here.
20466a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    Add<HStoreNamedField>(
20476a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org        result, HObjectAccess::ForMap(),
20486a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org        Add<HConstant>(isolate()->factory()->cons_string_map()));
20490f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  }
20500f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  if_onebyte.End();
20510f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
20520f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // Initialize the cons string fields.
20530f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(),
20540a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                        Add<HConstant>(String::kEmptyHashField));
20550a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length);
20560a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  Add<HStoreNamedField>(result, HObjectAccess::ForConsStringFirst(), left);
20570a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  Add<HStoreNamedField>(result, HObjectAccess::ForConsStringSecond(), right);
20580f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
20590f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // Count the native string addition.
20600f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  AddIncrementCounter(isolate()->counters()->string_add_native());
20610f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
20620f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  return result;
20630cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org}
20640cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
20650cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
20660cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.orgvoid HGraphBuilder::BuildCopySeqStringChars(HValue* src,
20670cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org                                            HValue* src_offset,
20680cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org                                            String::Encoding src_encoding,
20690cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org                                            HValue* dst,
20700cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org                                            HValue* dst_offset,
20710cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org                                            String::Encoding dst_encoding,
20720cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org                                            HValue* length) {
20730cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  ASSERT(dst_encoding != String::ONE_BYTE_ENCODING ||
20740cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org         src_encoding == String::ONE_BYTE_ENCODING);
20750cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement);
20760cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  HValue* index = loop.BeginBody(graph()->GetConstant0(), length, Token::LT);
20770cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  {
20787ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org    HValue* src_index = AddUncasted<HAdd>(src_offset, index);
2079f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    HValue* value =
2080f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org        AddUncasted<HSeqStringGetChar>(src_encoding, src, src_index);
20817ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org    HValue* dst_index = AddUncasted<HAdd>(dst_offset, index);
20820cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    Add<HSeqStringSetChar>(dst_encoding, dst, dst_index, value);
20830cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  }
20840cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  loop.EndBody();
20850cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org}
20860cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
20870cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
2088895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.orgHValue* HGraphBuilder::BuildObjectSizeAlignment(
2089895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    HValue* unaligned_size, int header_size) {
2090895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  ASSERT((header_size & kObjectAlignmentMask) == 0);
2091895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  HValue* size = AddUncasted<HAdd>(
2092895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      unaligned_size, Add<HConstant>(static_cast<int32_t>(
2093895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org          header_size + kObjectAlignmentMask)));
2094895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  size->ClearFlag(HValue::kCanOverflow);
2095895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  return AddUncasted<HBitwise>(
2096895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      Token::BIT_AND, size, Add<HConstant>(static_cast<int32_t>(
2097895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org          ~kObjectAlignmentMask)));
2098895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org}
2099895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
2100895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
21010f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.orgHValue* HGraphBuilder::BuildUncheckedStringAdd(
21020f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    HValue* left,
21030f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    HValue* right,
21040f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    HAllocationMode allocation_mode) {
21050cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  // Determine the string lengths.
21060f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HValue* left_length = AddLoadStringLength(left);
21070f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HValue* right_length = AddLoadStringLength(right);
21080cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
21090f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // Compute the combined string length.
21100f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HValue* length = BuildAddStringLengths(left_length, right_length);
2111f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
21120f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // Do some manual constant folding here.
21130f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  if (left_length->IsConstant()) {
21140f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    HConstant* c_left_length = HConstant::cast(left_length);
21150f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    ASSERT_NE(0, c_left_length->Integer32Value());
21160f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    if (c_left_length->Integer32Value() + 1 >= ConsString::kMinLength) {
21170f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      // The right string contains at least one character.
21180f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      return BuildCreateConsString(length, left, right, allocation_mode);
21190f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    }
21200f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  } else if (right_length->IsConstant()) {
21210f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    HConstant* c_right_length = HConstant::cast(right_length);
21220f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    ASSERT_NE(0, c_right_length->Integer32Value());
21230f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    if (c_right_length->Integer32Value() + 1 >= ConsString::kMinLength) {
21240f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      // The left string contains at least one character.
21250f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      return BuildCreateConsString(length, left, right, allocation_mode);
21260f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    }
21270f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  }
2128f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
2129f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  // Check if we should create a cons string.
2130f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  IfBuilder if_createcons(this);
2131f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  if_createcons.If<HCompareNumericAndBranch>(
2132f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      length, Add<HConstant>(ConsString::kMinLength), Token::GTE);
2133f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  if_createcons.Then();
21340cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  {
21350f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    // Create a cons string.
21360f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    Push(BuildCreateConsString(length, left, right, allocation_mode));
2137f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  }
2138f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  if_createcons.Else();
2139f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  {
21400f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    // Determine the string instance types.
21410f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    HValue* left_instance_type = AddLoadStringInstanceType(left);
21420f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    HValue* right_instance_type = AddLoadStringInstanceType(right);
21430f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
21440f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    // Compute union and difference of instance types.
2145f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    HValue* ored_instance_types = AddUncasted<HBitwise>(
2146f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org        Token::BIT_OR, left_instance_type, right_instance_type);
21470f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    HValue* xored_instance_types = AddUncasted<HBitwise>(
21480f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org        Token::BIT_XOR, left_instance_type, right_instance_type);
2149f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
2150f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    // Check if both strings have the same encoding and both are
2151f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    // sequential.
2152f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    IfBuilder if_sameencodingandsequential(this);
2153f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    if_sameencodingandsequential.If<HCompareNumericAndBranch>(
2154f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org        AddUncasted<HBitwise>(
2155f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org            Token::BIT_AND, xored_instance_types,
2156f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org            Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))),
2157f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org        graph()->GetConstant0(), Token::EQ);
2158f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    if_sameencodingandsequential.And();
2159f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    STATIC_ASSERT(kSeqStringTag == 0);
2160f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    if_sameencodingandsequential.If<HCompareNumericAndBranch>(
2161f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org        AddUncasted<HBitwise>(
2162f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org            Token::BIT_AND, ored_instance_types,
2163f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org            Add<HConstant>(static_cast<int32_t>(kStringRepresentationMask))),
2164f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org        graph()->GetConstant0(), Token::EQ);
2165f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    if_sameencodingandsequential.Then();
2166f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    {
21670f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      HConstant* string_map =
21680f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org          Add<HConstant>(isolate()->factory()->string_map());
21690f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      HConstant* ascii_string_map =
21700f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org          Add<HConstant>(isolate()->factory()->ascii_string_map());
21710f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
21720f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      // Determine map and size depending on whether result is one-byte string.
21730cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org      IfBuilder if_onebyte(this);
21740cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org      STATIC_ASSERT(kOneByteStringTag != 0);
21750cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org      if_onebyte.If<HCompareNumericAndBranch>(
21767ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org          AddUncasted<HBitwise>(
2177f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org              Token::BIT_AND, ored_instance_types,
2178f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org              Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))),
21790cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org          graph()->GetConstant0(), Token::NE);
21800cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org      if_onebyte.Then();
21810cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org      {
21820f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org        // Allocate sequential one-byte string object.
21830f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org        Push(length);
21840f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org        Push(ascii_string_map);
21850f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      }
21860f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      if_onebyte.Else();
21870f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      {
21880f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org        // Allocate sequential two-byte string object.
21890f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org        HValue* size = AddUncasted<HShl>(length, graph()->GetConstant1());
21900f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org        size->ClearFlag(HValue::kCanOverflow);
21910f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org        size->SetFlag(HValue::kUint32);
21920f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org        Push(size);
21930f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org        Push(string_map);
21940f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      }
21950f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      if_onebyte.End();
21960f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      HValue* map = Pop();
21970f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
21980f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      // Calculate the number of bytes needed for the characters in the
21990f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      // string while observing object alignment.
22000f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      STATIC_ASSERT((SeqString::kHeaderSize & kObjectAlignmentMask) == 0);
2201895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      HValue* size = BuildObjectSizeAlignment(Pop(), SeqString::kHeaderSize);
22020f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
22030f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      // Allocate the string object. HAllocate does not care whether we pass
22040f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      // STRING_TYPE or ASCII_STRING_TYPE here, so we just use STRING_TYPE here.
22050f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      HAllocate* result = BuildAllocate(
22060f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org          size, HType::String(), STRING_TYPE, allocation_mode);
22076a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      Add<HStoreNamedField>(result, HObjectAccess::ForMap(), map);
22080f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
22090f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      // Initialize the string fields.
22100f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(),
22110a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                            Add<HConstant>(String::kEmptyHashField));
22120a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length);
22130f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
22140f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      // Copy characters to the result string.
22150f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      IfBuilder if_twobyte(this);
22160f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      if_twobyte.If<HCompareObjectEqAndBranch>(map, string_map);
22170f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      if_twobyte.Then();
22180f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      {
22190f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org        // Copy characters from the left string.
2220f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org        BuildCopySeqStringChars(
22210f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org            left, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
22220f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org            result, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
2223f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org            left_length);
2224f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
22250f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org        // Copy characters from the right string.
2226f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org        BuildCopySeqStringChars(
22270f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org            right, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
22280f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org            result, left_length, String::TWO_BYTE_ENCODING,
2229f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org            right_length);
22300cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org      }
22310f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      if_twobyte.Else();
22320cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org      {
22330f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org        // Copy characters from the left string.
2234f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org        BuildCopySeqStringChars(
22350f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org            left, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
22360f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org            result, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
2237f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org            left_length);
2238f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
22390f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org        // Copy characters from the right string.
2240f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org        BuildCopySeqStringChars(
22410f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org            right, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
22420f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org            result, left_length, String::ONE_BYTE_ENCODING,
2243f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org            right_length);
22440cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org      }
22450f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      if_twobyte.End();
22460cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
2247f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      // Count the native string addition.
2248f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      AddIncrementCounter(isolate()->counters()->string_add_native());
2249f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
22500f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      // Return the sequential string.
22510f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      Push(result);
22520cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    }
2253f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    if_sameencodingandsequential.Else();
22540cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    {
2255f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      // Fallback to the runtime to add the two strings.
22568d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      Add<HPushArguments>(left, right);
22579b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org      Push(Add<HCallRuntime>(
22589b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org            isolate()->factory()->empty_string(),
22599b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org            Runtime::FunctionForId(Runtime::kHiddenStringAdd),
22609b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org            2));
22610cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    }
2262f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    if_sameencodingandsequential.End();
22630cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  }
2264f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  if_createcons.End();
22650cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
22660cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  return Pop();
22670cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org}
22680cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
22690cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
22700f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.orgHValue* HGraphBuilder::BuildStringAdd(
22710f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    HValue* left,
22720f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    HValue* right,
22730f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    HAllocationMode allocation_mode) {
22740f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  NoObservableSideEffectsScope no_effects(this);
22750f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
22760f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  // Determine string lengths.
22770f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HValue* left_length = AddLoadStringLength(left);
22780f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HValue* right_length = AddLoadStringLength(right);
22790cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
22800cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  // Check if left string is empty.
22810f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  IfBuilder if_leftempty(this);
22820f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  if_leftempty.If<HCompareNumericAndBranch>(
22830cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org      left_length, graph()->GetConstant0(), Token::EQ);
22840f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  if_leftempty.Then();
22850cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  {
22860cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    // Count the native string addition.
22870cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    AddIncrementCounter(isolate()->counters()->string_add_native());
22880cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
22890cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    // Just return the right string.
22900cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    Push(right);
22910cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  }
22920f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  if_leftempty.Else();
22930cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  {
22940cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    // Check if right string is empty.
22950f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    IfBuilder if_rightempty(this);
22960f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    if_rightempty.If<HCompareNumericAndBranch>(
22970cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org        right_length, graph()->GetConstant0(), Token::EQ);
22980f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    if_rightempty.Then();
22990cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    {
23000cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org      // Count the native string addition.
23010cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org      AddIncrementCounter(isolate()->counters()->string_add_native());
23020cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
23030cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org      // Just return the left string.
23040cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org      Push(left);
23050cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    }
23060f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    if_rightempty.Else();
23070cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    {
23080f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      // Add the two non-empty strings.
23090f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      Push(BuildUncheckedStringAdd(left, right, allocation_mode));
23100cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    }
23110f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    if_rightempty.End();
23120cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  }
23130f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  if_leftempty.End();
23140cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
23150cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  return Pop();
23160cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org}
23170cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
23180cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
2319a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
23201e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    HValue* checked_object,
2321a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    HValue* key,
2322a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    HValue* val,
2323a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    bool is_js_array,
2324a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    ElementsKind elements_kind,
2325f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    PropertyAccessType access_type,
2326906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    LoadKeyedHoleMode load_mode,
232753ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org    KeyedAccessStoreMode store_mode) {
23285c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  ASSERT((!IsExternalArrayElementsKind(elements_kind) &&
23295c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org              !IsFixedTypedArrayElementsKind(elements_kind)) ||
23305c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org         !is_js_array);
2331a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // No GVNFlag is necessary for ElementsKind if there is an explicit dependency
2332a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // on a HElementsTransition instruction. The flag can also be removed if the
2333a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // map to check has FAST_HOLEY_ELEMENTS, since there can be no further
2334a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // ElementsKind transitions. Finally, the dependency can be removed for stores
2335a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the
2336a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // generated store code.
2337a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if ((elements_kind == FAST_HOLEY_ELEMENTS) ||
2338f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      (elements_kind == FAST_ELEMENTS && access_type == STORE)) {
2339f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    checked_object->ClearDependsOnFlag(kElementsKind);
2340a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
23411e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org
2342a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind);
2343a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  bool fast_elements = IsFastObjectElementsKind(elements_kind);
23441e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  HValue* elements = AddLoadElements(checked_object);
2345f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (access_type == STORE && (fast_elements || fast_smi_only_elements) &&
23467bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org      store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
2347d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    HCheckMaps* check_cow_map = Add<HCheckMaps>(
2348af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org        elements, isolate()->factory()->fixed_array_map());
2349f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    check_cow_map->ClearDependsOnFlag(kElementsKind);
2350a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
2351a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  HInstruction* length = NULL;
23527bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  if (is_js_array) {
2353ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org    length = Add<HLoadNamedField>(
23545924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org        checked_object->ActualValue(), checked_object,
235509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org        HObjectAccess::ForArrayLength(elements_kind));
23567bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  } else {
2357c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    length = AddLoadFixedArrayLength(elements);
23587bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  }
2359c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  length->set_type(HType::Smi());
23607bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  HValue* checked_key = NULL;
23615c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  if (IsExternalArrayElementsKind(elements_kind) ||
23625c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org      IsFixedTypedArrayElementsKind(elements_kind)) {
23635c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    HValue* backing_store;
23645c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    if (IsExternalArrayElementsKind(elements_kind)) {
236505150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org      backing_store = Add<HLoadNamedField>(
236609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org          elements, static_cast<HValue*>(NULL),
236709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org          HObjectAccess::ForExternalArrayExternalPointer());
23685c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    } else {
23695c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org      backing_store = elements;
23705c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org    }
23717bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org    if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
2372b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      NoObservableSideEffectsScope no_effects(this);
23732d18b3604565efb0b4d300dd899901ed866eaaaedanno@chromium.org      IfBuilder length_checker(this);
2374e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org      length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT);
2375b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      length_checker.Then();
237677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org      IfBuilder negative_checker(this);
2377e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org      HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>(
2378b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org          key, graph()->GetConstant0(), Token::GTE);
237977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org      negative_checker.Then();
2380b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org      HInstruction* result = AddElementAccess(
2381f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          backing_store, key, val, bounds_check, elements_kind, access_type);
2382594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      negative_checker.ElseDeopt("Negative key encountered");
2383ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      negative_checker.End();
23847bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org      length_checker.End();
23857bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org      return result;
23867bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org    } else {
23877bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org      ASSERT(store_mode == STANDARD_STORE);
23881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      checked_key = Add<HBoundsCheck>(key, length);
2389b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org      return AddElementAccess(
23905c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org          backing_store, checked_key, val,
2391f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          checked_object, elements_kind, access_type);
23927bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org    }
2393a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
2394a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  ASSERT(fast_smi_only_elements ||
2395a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org         fast_elements ||
2396a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org         IsFastDoubleElementsKind(elements_kind));
23977bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
239853ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  // In case val is stored into a fast smi array, assure that the value is a smi
239953ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  // before manipulating the backing store. Otherwise the actual store may
240053ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  // deopt, leaving the backing store in an invalid state.
2401f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (access_type == STORE && IsFastSmiElementsKind(elements_kind) &&
24027bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org      !val->type().IsSmi()) {
24039af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org    val = AddUncasted<HForceRepresentation>(val, Representation::Smi());
24047bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  }
24057bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
24067bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  if (IsGrowStoreMode(store_mode)) {
2407e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    NoObservableSideEffectsScope no_effects(this);
2408804712e3d40723ca745704121c814fe52e8e6158verwaest@chromium.org    Representation representation = HStoreKeyed::RequiredValueRepresentation(
2409804712e3d40723ca745704121c814fe52e8e6158verwaest@chromium.org        elements_kind, STORE_TO_INITIALIZED_ENTRY);
2410804712e3d40723ca745704121c814fe52e8e6158verwaest@chromium.org    val = AddUncasted<HForceRepresentation>(val, representation);
24111e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    elements = BuildCheckForCapacityGrow(checked_object, elements,
24121e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org                                         elements_kind, length, key,
2413f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                         is_js_array, access_type);
2414a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    checked_key = key;
2415a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  } else {
24161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    checked_key = Add<HBoundsCheck>(key, length);
24177bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
2418f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (access_type == STORE && (fast_elements || fast_smi_only_elements)) {
24197bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org      if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) {
2420e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        NoObservableSideEffectsScope no_effects(this);
24211e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org        elements = BuildCopyElementsOnWrite(checked_object, elements,
24221e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org                                            elements_kind, length);
24237bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org      } else {
2424d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        HCheckMaps* check_cow_map = Add<HCheckMaps>(
2425af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org            elements, isolate()->factory()->fixed_array_map());
2426f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        check_cow_map->ClearDependsOnFlag(kElementsKind);
24277bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org      }
24287bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org    }
2429a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
2430b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  return AddElementAccess(elements, checked_key, val, checked_object,
2431f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                          elements_kind, access_type, load_mode);
2432a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
2433a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
2434a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
2435b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.orgHValue* HGraphBuilder::BuildAllocateArrayFromLength(
2436b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    JSArrayBuilder* array_builder,
2437b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    HValue* length_argument) {
2438b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (length_argument->IsConstant() &&
2439b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      HConstant::cast(length_argument)->HasSmiValue()) {
2440b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    int array_length = HConstant::cast(length_argument)->Integer32Value();
244138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    if (array_length == 0) {
244238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      return array_builder->AllocateEmptyArray();
244338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    } else {
244438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      return array_builder->AllocateArray(length_argument,
244538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                          array_length,
244638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                          length_argument);
244738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    }
2448b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  }
2449b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
2450b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  HValue* constant_zero = graph()->GetConstant0();
2451b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  HConstant* max_alloc_length =
2452b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      Add<HConstant>(JSObject::kInitialMaxFastElementArray);
2453b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  HInstruction* checked_length = Add<HBoundsCheck>(length_argument,
2454b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                                   max_alloc_length);
2455b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  IfBuilder if_builder(this);
2456b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if_builder.If<HCompareNumericAndBranch>(checked_length, constant_zero,
2457b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                          Token::EQ);
2458b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if_builder.Then();
2459b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  const int initial_capacity = JSArray::kPreallocatedArrayElements;
2460b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  HConstant* initial_capacity_node = Add<HConstant>(initial_capacity);
2461b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Push(initial_capacity_node);  // capacity
2462b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Push(constant_zero);          // length
2463b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if_builder.Else();
2464b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (!(top_info()->IsStub()) &&
2465b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      IsFastPackedElementsKind(array_builder->kind())) {
2466b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    // We'll come back later with better (holey) feedback.
2467b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    if_builder.Deopt("Holey array despite packed elements_kind feedback");
2468ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  } else {
2469ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    Push(checked_length);         // capacity
2470ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    Push(checked_length);         // length
2471b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  }
2472b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if_builder.End();
2473b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
2474b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  // Figure out total size
2475b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  HValue* length = Pop();
2476b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  HValue* capacity = Pop();
247738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  return array_builder->AllocateArray(capacity, max_alloc_length, length);
2478b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org}
2479b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
24806a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org
248138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgHValue* HGraphBuilder::BuildCalculateElementsSize(ElementsKind kind,
248238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                                  HValue* capacity) {
248338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  int elements_size = IsFastDoubleElementsKind(kind)
248438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      ? kDoubleSize
248538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      : kPointerSize;
248694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
24871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HConstant* elements_size_value = Add<HConstant>(elements_size);
248838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HInstruction* mul = HMul::NewImul(zone(), context(),
248938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                    capacity->ActualValue(),
249038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                    elements_size_value);
249138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  AddInstruction(mul);
249294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  mul->ClearFlag(HValue::kCanOverflow);
249394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
249438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  STATIC_ASSERT(FixedDoubleArray::kHeaderSize == FixedArray::kHeaderSize);
249538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
24961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize);
24977ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  HValue* total_size = AddUncasted<HAdd>(mul, header_size);
249894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  total_size->ClearFlag(HValue::kCanOverflow);
249938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  return total_size;
250038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org}
250138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
250238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
250338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgHAllocate* HGraphBuilder::AllocateJSArrayObject(AllocationSiteMode mode) {
250438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  int base_size = JSArray::kSize;
250538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  if (mode == TRACK_ALLOCATION_SITE) {
250638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    base_size += AllocationMemento::kSize;
250738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  }
250838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HConstant* size_in_bytes = Add<HConstant>(base_size);
250938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  return Add<HAllocate>(
251038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      size_in_bytes, HType::JSArray(), NOT_TENURED, JS_OBJECT_TYPE);
251138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org}
251238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
251338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
251438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgHConstant* HGraphBuilder::EstablishElementsAllocationSize(
251538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    ElementsKind kind,
251638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    int capacity) {
251738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  int base_size = IsFastDoubleElementsKind(kind)
251838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      ? FixedDoubleArray::SizeFor(capacity)
251938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      : FixedArray::SizeFor(capacity);
252094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
252138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  return Add<HConstant>(base_size);
252238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org}
252338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
252438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
252538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgHAllocate* HGraphBuilder::BuildAllocateElements(ElementsKind kind,
252638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                                HValue* size_in_bytes) {
252738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  InstanceType instance_type = IsFastDoubleElementsKind(kind)
252838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      ? FIXED_DOUBLE_ARRAY_TYPE
252938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      : FIXED_ARRAY_TYPE;
253038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
253138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  return Add<HAllocate>(size_in_bytes, HType::HeapObject(), NOT_TENURED,
2532d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org                        instance_type);
2533e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
2534e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
253594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
2536c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.orgvoid HGraphBuilder::BuildInitializeElementsHeader(HValue* elements,
2537c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org                                                  ElementsKind kind,
2538c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org                                                  HValue* capacity) {
2539750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Factory* factory = isolate()->factory();
254094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  Handle<Map> map = IsFastDoubleElementsKind(kind)
254194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      ? factory->fixed_double_array_map()
254294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      : factory->fixed_array_map();
254394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
25446a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  Add<HStoreNamedField>(elements, HObjectAccess::ForMap(), Add<HConstant>(map));
2545d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(),
25460a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                        capacity);
2547e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
254894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
2549e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
2550c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.orgHValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader(
2551c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    ElementsKind kind,
2552c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    HValue* capacity) {
2553d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // The HForceRepresentation is to prevent possible deopt on int-smi
2554d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // conversion after allocation but before the new object fields are set.
25559af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  capacity = AddUncasted<HForceRepresentation>(capacity, Representation::Smi());
255638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HValue* size_in_bytes = BuildCalculateElementsSize(kind, capacity);
255738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HValue* new_elements = BuildAllocateElements(kind, size_in_bytes);
2558c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  BuildInitializeElementsHeader(new_elements, kind, capacity);
2559e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  return new_elements;
256094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org}
256194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
256294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
256338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgvoid HGraphBuilder::BuildJSArrayHeader(HValue* array,
256438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                       HValue* array_map,
256538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                       HValue* elements,
256638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                       AllocationSiteMode mode,
256738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                       ElementsKind elements_kind,
256838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                       HValue* allocation_site_payload,
256938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                       HValue* length_field) {
25700a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map);
2571ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
2572ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  HConstant* empty_fixed_array =
2573d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    Add<HConstant>(isolate()->factory()->empty_fixed_array());
2574ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
257538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  Add<HStoreNamedField>(
257638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      array, HObjectAccess::ForPropertiesPointer(), empty_fixed_array);
257738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
257838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  Add<HStoreNamedField>(
257938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      array, HObjectAccess::ForElementsPointer(),
258038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      elements != NULL ? elements : empty_fixed_array);
258138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
258238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  Add<HStoreNamedField>(
258338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      array, HObjectAccess::ForArrayLength(elements_kind), length_field);
2584ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
2585ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  if (mode == TRACK_ALLOCATION_SITE) {
2586ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    BuildCreateAllocationMemento(
2587ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org        array, Add<HConstant>(JSArray::kSize), allocation_site_payload);
2588ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
2589ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
2590ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
2591ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
2592b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.orgHInstruction* HGraphBuilder::AddElementAccess(
2593b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    HValue* elements,
2594ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    HValue* checked_key,
2595ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    HValue* val,
2596ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    HValue* dependency,
2597ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    ElementsKind elements_kind,
2598f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    PropertyAccessType access_type,
2599b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    LoadKeyedHoleMode load_mode) {
2600f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (access_type == STORE) {
2601ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    ASSERT(val != NULL);
2602af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    if (elements_kind == EXTERNAL_UINT8_CLAMPED_ELEMENTS ||
26035c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org        elements_kind == UINT8_CLAMPED_ELEMENTS) {
2604b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org      val = Add<HClampToUint8>(val);
2605ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    }
260671ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org    return Add<HStoreKeyed>(elements, checked_key, val, elements_kind,
2607804712e3d40723ca745704121c814fe52e8e6158verwaest@chromium.org                            STORE_TO_INITIALIZED_ENTRY);
2608ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  }
2609ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
2610f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  ASSERT(access_type == LOAD);
2611b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  ASSERT(val == NULL);
2612b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  HLoadKeyed* load = Add<HLoadKeyed>(
2613b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org      elements, checked_key, dependency, elements_kind, load_mode);
2614b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  if (FLAG_opt_safe_uint32_operations &&
2615af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      (elements_kind == EXTERNAL_UINT32_ELEMENTS ||
26165c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org       elements_kind == UINT32_ELEMENTS)) {
2617b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    graph()->RecordUint32Instruction(load);
2618ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  }
2619b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  return load;
2620ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org}
2621ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
2622ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
262338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgHLoadNamedField* HGraphBuilder::AddLoadMap(HValue* object,
262438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                           HValue* dependency) {
262538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  return Add<HLoadNamedField>(object, dependency, HObjectAccess::ForMap());
262638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org}
262738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
262838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
2629a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.orgHLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object,
2630a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                                HValue* dependency) {
263109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  return Add<HLoadNamedField>(
2632a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      object, dependency, HObjectAccess::ForElementsPointer());
263357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org}
263457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
263557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
2636a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.orgHLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength(
2637a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    HValue* array,
2638a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    HValue* dependency) {
263909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  return Add<HLoadNamedField>(
2640a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      array, dependency, HObjectAccess::ForFixedArrayLength());
2641a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org}
2642a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
2643a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
2644a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.orgHLoadNamedField* HGraphBuilder::AddLoadArrayLength(HValue* array,
2645a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                                   ElementsKind kind,
2646a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                                   HValue* dependency) {
2647a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  return Add<HLoadNamedField>(
2648a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      array, dependency, HObjectAccess::ForArrayLength(kind));
2649c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org}
2650c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org
2651c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org
2652d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgHValue* HGraphBuilder::BuildNewElementsCapacity(HValue* old_capacity) {
2653dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  HValue* half_old_capacity = AddUncasted<HShr>(old_capacity,
2654dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org                                                graph_->GetConstant1());
26557bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
2656dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  HValue* new_capacity = AddUncasted<HAdd>(half_old_capacity, old_capacity);
26577bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  new_capacity->ClearFlag(HValue::kCanOverflow);
26587bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
26591510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HValue* min_growth = Add<HConstant>(16);
26607bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
2661dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  new_capacity = AddUncasted<HAdd>(new_capacity, min_growth);
26627bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  new_capacity->ClearFlag(HValue::kCanOverflow);
26637bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
26647bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  return new_capacity;
26657bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org}
26667bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
26677bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
26687bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgHValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object,
26697bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                                 HValue* elements,
26707bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                                 ElementsKind kind,
2671bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org                                                 ElementsKind new_kind,
26727bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                                 HValue* length,
26732d18b3604565efb0b4d300dd899901ed866eaaaedanno@chromium.org                                                 HValue* new_capacity) {
26743c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  Add<HBoundsCheck>(new_capacity, Add<HConstant>(
26753c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org          (Page::kMaxRegularHeapObjectSize - FixedArray::kHeaderSize) >>
26763c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org          ElementsKindToShiftSize(kind)));
26777bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
2678c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  HValue* new_elements = BuildAllocateElementsAndInitializeElementsHeader(
2679d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      new_kind, new_capacity);
26807bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
268138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  BuildCopyElements(elements, kind, new_elements,
2682a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                    new_kind, length, new_capacity);
26837bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
2684d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
26850a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                        new_elements);
26867bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
26877bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  return new_elements;
26887bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org}
26897bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
26907bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
269138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgvoid HGraphBuilder::BuildFillElementsWithValue(HValue* elements,
269238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                               ElementsKind elements_kind,
269338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                               HValue* from,
269438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                               HValue* to,
269538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                               HValue* value) {
2696a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  if (to == NULL) {
2697a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    to = AddLoadFixedArrayLength(elements);
2698a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  }
2699a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
2700ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // Special loop unfolding case
27017e6132b924829c353864933f29124419916db550machenbach@chromium.org  STATIC_ASSERT(JSArray::kPreallocatedArrayElements <=
27027e6132b924829c353864933f29124419916db550machenbach@chromium.org                kElementLoopUnrollThreshold);
2703b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  int initial_capacity = -1;
2704ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  if (from->IsInteger32Constant() && to->IsInteger32Constant()) {
2705ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    int constant_from = from->GetInteger32Constant();
2706ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    int constant_to = to->GetInteger32Constant();
27077bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
27087e6132b924829c353864933f29124419916db550machenbach@chromium.org    if (constant_from == 0 && constant_to <= kElementLoopUnrollThreshold) {
2709ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      initial_capacity = constant_to;
2710ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    }
2711ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
27127bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
271353ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  // Since we're about to store a hole value, the store instruction below must
271453ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  // assume an elements kind that supports heap object values.
271553ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  if (IsFastSmiOrObjectElementsKind(elements_kind)) {
271653ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org    elements_kind = FAST_HOLEY_ELEMENTS;
271753ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org  }
271853ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org
2719b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (initial_capacity >= 0) {
2720ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    for (int i = 0; i < initial_capacity; i++) {
27211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      HInstruction* key = Add<HConstant>(i);
272238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      Add<HStoreKeyed>(elements, key, value, elements_kind);
2723ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    }
2724ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  } else {
2725a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    // Carefully loop backwards so that the "from" remains live through the loop
2726a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    // rather than the to. This often corresponds to keeping length live rather
2727a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    // then capacity, which helps register allocation, since length is used more
2728a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    // other than capacity after filling with holes.
2729a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement);
2730a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
2731a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    HValue* key = builder.BeginBody(to, from, Token::GT);
27327bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
2733a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    HValue* adjusted_key = AddUncasted<HSub>(key, graph()->GetConstant1());
2734a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    adjusted_key->ClearFlag(HValue::kCanOverflow);
2735ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
273638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    Add<HStoreKeyed>(elements, adjusted_key, value, elements_kind);
2737ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
2738ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    builder.EndBody();
2739ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
27407bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org}
27417bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
27427bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
274338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgvoid HGraphBuilder::BuildFillElementsWithHole(HValue* elements,
274438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                              ElementsKind elements_kind,
274538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                              HValue* from,
274638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                              HValue* to) {
274738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  // Fast elements kinds need to be initialized in case statements below cause a
274838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  // garbage collection.
274938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  Factory* factory = isolate()->factory();
275038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
275138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  double nan_double = FixedDoubleArray::hole_nan_as_double();
275238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind)
275338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      ? Add<HConstant>(factory->the_hole_value())
275438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      : Add<HConstant>(nan_double);
275538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
275638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  BuildFillElementsWithValue(elements, elements_kind, from, to, hole);
275738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org}
275838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
275938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
276038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgvoid HGraphBuilder::BuildCopyElements(HValue* from_elements,
276194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org                                      ElementsKind from_elements_kind,
276294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org                                      HValue* to_elements,
276394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org                                      ElementsKind to_elements_kind,
27647bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                      HValue* length,
27652d18b3604565efb0b4d300dd899901ed866eaaaedanno@chromium.org                                      HValue* capacity) {
2766a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  int constant_capacity = -1;
2767a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  if (capacity != NULL &&
2768a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      capacity->IsConstant() &&
2769a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      HConstant::cast(capacity)->HasInteger32Value()) {
2770a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    int constant_candidate = HConstant::cast(capacity)->Integer32Value();
2771e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    if (constant_candidate <= kElementLoopUnrollThreshold) {
2772a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      constant_capacity = constant_candidate;
2773a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    }
2774a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  }
2775a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
2776e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  bool pre_fill_with_holes =
2777e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    IsFastDoubleElementsKind(from_elements_kind) &&
2778e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    IsFastObjectElementsKind(to_elements_kind);
2779e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  if (pre_fill_with_holes) {
2780e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    // If the copy might trigger a GC, make sure that the FixedArray is
2781e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    // pre-initialized with holes to make sure that it's always in a
2782e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    // consistent state.
2783e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    BuildFillElementsWithHole(to_elements, to_elements_kind,
2784e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                              graph()->GetConstant0(), NULL);
2785e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  }
2786e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org
2787a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  if (constant_capacity != -1) {
2788a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    // Unroll the loop for small elements kinds.
2789a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    for (int i = 0; i < constant_capacity; i++) {
2790a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      HValue* key_constant = Add<HConstant>(i);
2791a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      HInstruction* value = Add<HLoadKeyed>(from_elements, key_constant,
2792a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                            static_cast<HValue*>(NULL),
2793a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                            from_elements_kind);
2794a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      Add<HStoreKeyed>(to_elements, key_constant, value, to_elements_kind);
2795a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    }
2796a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  } else {
2797e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    if (!pre_fill_with_holes &&
2798e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org        (capacity == NULL || !length->Equals(capacity))) {
2799a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      BuildFillElementsWithHole(to_elements, to_elements_kind,
2800a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                length, NULL);
2801a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    }
280294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
2803a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    if (capacity == NULL) {
2804a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      capacity = AddLoadFixedArrayLength(to_elements);
2805a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    }
2806a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
2807a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement);
2808a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org
2809a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    HValue* key = builder.BeginBody(length, graph()->GetConstant0(),
2810a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                    Token::GT);
281194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
2812a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    key = AddUncasted<HSub>(key, graph()->GetConstant1());
2813a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    key->ClearFlag(HValue::kCanOverflow);
2814a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
2815a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    HValue* element = Add<HLoadKeyed>(from_elements, key,
2816a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                      static_cast<HValue*>(NULL),
2817a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                      from_elements_kind,
2818a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                      ALLOW_RETURN_HOLE);
2819a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org
2820a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    ElementsKind kind = (IsHoleyElementsKind(from_elements_kind) &&
2821a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                         IsFastSmiElementsKind(to_elements_kind))
282253ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org      ? FAST_HOLEY_ELEMENTS : to_elements_kind;
2823c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org
2824a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    if (IsHoleyElementsKind(from_elements_kind) &&
2825a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org        from_elements_kind != to_elements_kind) {
2826a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      IfBuilder if_hole(this);
2827a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      if_hole.If<HCompareHoleAndBranch>(element);
2828a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      if_hole.Then();
2829a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      HConstant* hole_constant = IsFastDoubleElementsKind(to_elements_kind)
2830c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org        ? Add<HConstant>(FixedDoubleArray::hole_nan_as_double())
2831c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org        : graph()->GetConstantHole();
2832a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      Add<HStoreKeyed>(to_elements, key, hole_constant, kind);
2833a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      if_hole.Else();
2834a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind);
2835a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      store->SetFlag(HValue::kAllowUndefinedAsNaN);
2836a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      if_hole.End();
2837a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    } else {
2838a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind);
2839a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      store->SetFlag(HValue::kAllowUndefinedAsNaN);
2840a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    }
28417bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
2842a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    builder.EndBody();
28437bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  }
2844a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org
2845a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  Counters* counters = isolate()->counters();
2846a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  AddIncrementCounter(counters->inlined_copied_elements());
2847a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org}
2848a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org
2849865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org
2850a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.orgHValue* HGraphBuilder::BuildCloneShallowArrayCow(HValue* boilerplate,
2851a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                                 HValue* allocation_site,
2852a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                                 AllocationSiteMode mode,
2853a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                                 ElementsKind kind) {
285438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HAllocate* array = AllocateJSArrayObject(mode);
2855a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
285638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HValue* map = AddLoadMap(boilerplate);
2857a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  HValue* elements = AddLoadElements(boilerplate);
2858a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  HValue* length = AddLoadArrayLength(boilerplate, kind);
2859a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
286038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  BuildJSArrayHeader(array,
286138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                     map,
286238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                     elements,
286338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                     mode,
286438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                     FAST_ELEMENTS,
286538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                     allocation_site,
286638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                     length);
286738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  return array;
2868a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org}
2869a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
2870a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
2871a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.orgHValue* HGraphBuilder::BuildCloneShallowArrayEmpty(HValue* boilerplate,
2872a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                                   HValue* allocation_site,
2873a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                                   AllocationSiteMode mode) {
287438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HAllocate* array = AllocateJSArrayObject(mode);
2875a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
287638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HValue* map = AddLoadMap(boilerplate);
2877a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
287838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  BuildJSArrayHeader(array,
287938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                     map,
288038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                     NULL,  // set elements to empty fixed array
288138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                     mode,
288238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                     FAST_ELEMENTS,
288338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                     allocation_site,
288438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                     graph()->GetConstant0());
288538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  return array;
2886a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org}
2887a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
2888a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
2889a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.orgHValue* HGraphBuilder::BuildCloneShallowArrayNonEmpty(HValue* boilerplate,
2890a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                                      HValue* allocation_site,
2891a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                                      AllocationSiteMode mode,
2892a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                                      ElementsKind kind) {
2893a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  HValue* boilerplate_elements = AddLoadElements(boilerplate);
2894a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  HValue* capacity = AddLoadFixedArrayLength(boilerplate_elements);
289538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
289638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  // Generate size calculation code here in order to make it dominate
289738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  // the JSArray allocation.
289838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HValue* elements_size = BuildCalculateElementsSize(kind, capacity);
289938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
290038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  // Create empty JSArray object for now, store elimination should remove
290138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  // redundant initialization of elements and length fields and at the same
290238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  // time the object will be fully prepared for GC if it happens during
290338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  // elements allocation.
290438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HValue* result = BuildCloneShallowArrayEmpty(
290538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      boilerplate, allocation_site, mode);
290638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
290738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HAllocate* elements = BuildAllocateElements(kind, elements_size);
290838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
2909e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  // This function implicitly relies on the fact that the
2910e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  // FastCloneShallowArrayStub is called only for literals shorter than
291138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  // JSObject::kInitialMaxFastElementArray.
2912e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  // Can't add HBoundsCheck here because otherwise the stub will eager a frame.
291338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HConstant* size_upper_bound = EstablishElementsAllocationSize(
291438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      kind, JSObject::kInitialMaxFastElementArray);
291538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  elements->set_size_upper_bound(size_upper_bound);
2916e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
291738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  Add<HStoreNamedField>(result, HObjectAccess::ForElementsPointer(), elements);
2918a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
2919a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  // The allocation for the cloned array above causes register pressure on
2920a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  // machines with low register counts. Force a reload of the boilerplate
2921a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  // elements here to free up a register for the allocation to avoid unnecessary
2922a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  // spillage.
2923a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  boilerplate_elements = AddLoadElements(boilerplate);
2924a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  boilerplate_elements->SetFlag(HValue::kCantBeReplaced);
2925a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
2926a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  // Copy the elements array header.
2927a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) {
2928a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i);
2929a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    Add<HStoreNamedField>(elements, access,
2930a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org        Add<HLoadNamedField>(boilerplate_elements,
293138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                             static_cast<HValue*>(NULL), access));
2932a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  }
2933a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
2934a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  // And the result of the length
293538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HValue* length = AddLoadArrayLength(boilerplate, kind);
293638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  Add<HStoreNamedField>(result, HObjectAccess::ForArrayLength(kind), length);
2937a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
293838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  BuildCopyElements(boilerplate_elements, kind, elements,
2939a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                    kind, length, NULL);
2940a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  return result;
2941a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org}
2942a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
2943a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
2944ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgvoid HGraphBuilder::BuildCompareNil(
2945ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    HValue* value,
29466d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org    Type* type,
2947ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    HIfContinuation* continuation) {
294871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  IfBuilder if_nil(this);
2949ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org  bool some_case_handled = false;
2950ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org  bool some_case_missing = false;
2951ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org
295241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  if (type->Maybe(Type::Null())) {
2953ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org    if (some_case_handled) if_nil.Or();
2954ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    if_nil.If<HCompareObjectEqAndBranch>(value, graph()->GetConstantNull());
2955ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org    some_case_handled = true;
2956ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org  } else {
2957ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org    some_case_missing = true;
2958ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
2959ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org
296041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  if (type->Maybe(Type::Undefined())) {
2961ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org    if (some_case_handled) if_nil.Or();
2962ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    if_nil.If<HCompareObjectEqAndBranch>(value,
2963ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org                                         graph()->GetConstantUndefined());
2964ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org    some_case_handled = true;
2965ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org  } else {
2966ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org    some_case_missing = true;
2967ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
2968ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org
296941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  if (type->Maybe(Type::Undetectable())) {
2970ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org    if (some_case_handled) if_nil.Or();
2971ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    if_nil.If<HIsUndetectableAndBranch>(value);
2972ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org    some_case_handled = true;
2973ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  } else {
2974ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org    some_case_missing = true;
2975ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org  }
2976ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org
2977ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org  if (some_case_missing) {
2978ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    if_nil.Then();
2979ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    if_nil.Else();
298041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    if (type->NumClasses() == 1) {
29811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      BuildCheckHeapObject(value);
2982ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      // For ICs, the map checked below is a sentinel map that gets replaced by
2983ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      // the monomorphic map when the code is used as a template to generate a
2984ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      // new IC. For optimized functions, there is no sentinel map, the map
2985ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      // emitted below is the actual monomorphic map.
2986af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org      Add<HCheckMaps>(value, type->Classes().Current());
2987ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    } else {
2988594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      if_nil.Deopt("Too many undetectable types");
2989ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    }
2990ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
2991ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
2992ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  if_nil.CaptureContinuation(continuation);
2993ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
2994ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
2995ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
2996ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.orgvoid HGraphBuilder::BuildCreateAllocationMemento(
2997ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    HValue* previous_object,
2998ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    HValue* previous_object_size,
2999ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    HValue* allocation_site) {
3000ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org  ASSERT(allocation_site != NULL);
3001ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org  HInnerAllocatedObject* allocation_memento = Add<HInnerAllocatedObject>(
3002eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org      previous_object, previous_object_size, HType::HeapObject());
3003ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org  AddStoreMapConstant(
3004ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org      allocation_memento, isolate()->factory()->allocation_memento_map());
3005ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org  Add<HStoreNamedField>(
30060a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      allocation_memento,
30070a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      HObjectAccess::ForAllocationMementoSite(),
30080a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      allocation_site);
3009ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org  if (FLAG_allocation_site_pretenuring) {
3010ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    HValue* memento_create_count = Add<HLoadNamedField>(
301109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org        allocation_site, static_cast<HValue*>(NULL),
301209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org        HObjectAccess::ForAllocationSiteOffset(
30134ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org            AllocationSite::kPretenureCreateCountOffset));
3014ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    memento_create_count = AddUncasted<HAdd>(
3015ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org        memento_create_count, graph()->GetConstant1());
3016afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // This smi value is reset to zero after every gc, overflow isn't a problem
3017afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // since the counter is bounded by the new space size.
3018afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    memento_create_count->ClearFlag(HValue::kCanOverflow);
30196a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    Add<HStoreNamedField>(
3020ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org        allocation_site, HObjectAccess::ForAllocationSiteOffset(
30210a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org            AllocationSite::kPretenureCreateCountOffset), memento_create_count);
3022ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org  }
3023ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
3024ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3025ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3026034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.orgHInstruction* HGraphBuilder::BuildGetNativeContext(HValue* closure) {
3027034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  // Get the global context, then the native context
3028034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  HInstruction* context =
302909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      Add<HLoadNamedField>(closure, static_cast<HValue*>(NULL),
303009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org                           HObjectAccess::ForFunctionContextPointer());
303109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  HInstruction* global_object = Add<HLoadNamedField>(
303209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      context, static_cast<HValue*>(NULL),
3033034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org      HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
30340a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset(
3035034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org      GlobalObject::kNativeContextOffset);
303609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  return Add<HLoadNamedField>(
303709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      global_object, static_cast<HValue*>(NULL), access);
3038034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org}
3039034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org
3040034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org
3041d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgHInstruction* HGraphBuilder::BuildGetNativeContext() {
3042a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  // Get the global context, then the native context
304305150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org  HValue* global_object = Add<HLoadNamedField>(
304409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      context(), static_cast<HValue*>(NULL),
304509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
304605150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org  return Add<HLoadNamedField>(
304709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      global_object, static_cast<HValue*>(NULL),
30480a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      HObjectAccess::ForObservableJSObjectOffset(
30490a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org          GlobalObject::kNativeContextOffset));
305057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org}
305157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
305257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
3053d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgHInstruction* HGraphBuilder::BuildGetArrayFunction() {
3054d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* native_context = BuildGetNativeContext();
30551510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HInstruction* index =
30561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      Add<HConstant>(static_cast<int32_t>(Context::ARRAY_FUNCTION_INDEX));
30571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return Add<HLoadKeyed>(
30581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
305957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org}
306057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
306157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
3062ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgHGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder,
30631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    ElementsKind kind,
30641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    HValue* allocation_site_payload,
30651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    HValue* constructor_function,
30661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    AllocationSiteOverrideMode override_mode) :
3067ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org        builder_(builder),
3068ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org        kind_(kind),
3069d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org        allocation_site_payload_(allocation_site_payload),
30701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        constructor_function_(constructor_function) {
307143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  ASSERT(!allocation_site_payload->IsConstant() ||
307243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org         HConstant::cast(allocation_site_payload)->handle(
307343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org             builder_->isolate())->IsAllocationSite());
30741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  mode_ = override_mode == DISABLE_ALLOCATION_SITES
3075d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      ? DONT_TRACK_ALLOCATION_SITE
3076bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      : AllocationSite::GetMode(kind);
3077d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org}
3078d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
3079d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
3080d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgHGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder,
3081d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org                                              ElementsKind kind,
3082d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org                                              HValue* constructor_function) :
3083d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    builder_(builder),
3084d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    kind_(kind),
3085d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    mode_(DONT_TRACK_ALLOCATION_SITE),
3086d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    allocation_site_payload_(NULL),
3087d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    constructor_function_(constructor_function) {
3088ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
3089ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3090ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3091d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgHValue* HGraphBuilder::JSArrayBuilder::EmitMapCode() {
3092b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (!builder()->top_info()->IsStub()) {
3093b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    // A constant map is fine.
3094b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    Handle<Map> map(builder()->isolate()->get_initial_js_array_map(kind_),
3095b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                    builder()->isolate());
3096b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    return builder()->Add<HConstant>(map);
3097b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  }
3098b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
3099ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  if (constructor_function_ != NULL && kind_ == GetInitialFastElementsKind()) {
31001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    // No need for a context lookup if the kind_ matches the initial
31011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    // map, because we can just load the map in that case.
31021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
3103f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    return builder()->Add<HLoadNamedField>(
3104f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        constructor_function_, static_cast<HValue*>(NULL), access);
31051510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
3106a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
3107034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  // TODO(mvstanton): we should always have a constructor function if we
3108034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  // are creating a stub.
3109034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  HInstruction* native_context = constructor_function_ != NULL
3110034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org      ? builder()->BuildGetNativeContext(constructor_function_)
3111034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org      : builder()->BuildGetNativeContext();
3112034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org
31131510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HInstruction* index = builder()->Add<HConstant>(
31141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX));
3115a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
31161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HInstruction* map_array = builder()->Add<HLoadKeyed>(
31171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
3118a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
31191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HInstruction* kind_index = builder()->Add<HConstant>(kind_);
3120a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
31211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return builder()->Add<HLoadKeyed>(
31221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
3123ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
3124ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3125ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3126d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgHValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() {
3127d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  // Find the map near the constructor function
3128d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
3129f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  return builder()->Add<HLoadNamedField>(
3130f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      constructor_function_, static_cast<HValue*>(NULL), access);
3131d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org}
3132d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
3133d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
313438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgHAllocate* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() {
313538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HConstant* capacity = builder()->Add<HConstant>(initial_capacity());
313638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  return AllocateArray(capacity,
313738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                       capacity,
313838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                       builder()->graph()->GetConstant0());
3139ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
3140ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3141ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
314238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgHAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray(
314338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    HValue* capacity,
314438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    HConstant* capacity_upper_bound,
314538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    HValue* length_field,
314638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    FillMode fill_mode) {
314738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  return AllocateArray(capacity,
314838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                       capacity_upper_bound->GetInteger32Constant(),
314938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                       length_field,
315038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                       fill_mode);
3151ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
3152ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3153ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
315438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgHAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray(
315538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    HValue* capacity,
315638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    int capacity_upper_bound,
315738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    HValue* length_field,
315838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    FillMode fill_mode) {
315938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HConstant* elememts_size_upper_bound = capacity->IsInteger32Constant()
316038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      ? HConstant::cast(capacity)
316138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      : builder()->EstablishElementsAllocationSize(kind_, capacity_upper_bound);
3162ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
316338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HAllocate* array = AllocateArray(capacity, length_field, fill_mode);
316438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  if (!elements_location_->has_size_upper_bound()) {
316538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    elements_location_->set_size_upper_bound(elememts_size_upper_bound);
316638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  }
316738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  return array;
3168ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
3169ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3170ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
317138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgHAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray(
317238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    HValue* capacity,
317338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    HValue* length_field,
317438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    FillMode fill_mode) {
3175d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // These HForceRepresentations are because we store these as fields in the
3176d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // objects we construct, and an int32-to-smi HChange could deopt. Accept
3177d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // the deopt possibility now, before allocation occurs.
31789af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  capacity =
31799af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org      builder()->AddUncasted<HForceRepresentation>(capacity,
31809af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org                                                   Representation::Smi());
31819af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  length_field =
31829af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org      builder()->AddUncasted<HForceRepresentation>(length_field,
31839af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org                                                   Representation::Smi());
3184ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
318538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  // Generate size calculation code here in order to make it dominate
318638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  // the JSArray allocation.
318738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HValue* elements_size =
318838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      builder()->BuildCalculateElementsSize(kind_, capacity);
318938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
319038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  // Allocate (dealing with failure appropriately)
319138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  HAllocate* array_object = builder()->AllocateJSArrayObject(mode_);
3192e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org
3193ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // Fill in the fields: map, properties, length
3194d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  HValue* map;
31951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (allocation_site_payload_ == NULL) {
3196d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    map = EmitInternalMapCode();
3197d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  } else {
3198d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    map = EmitMapCode();
3199d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  }
3200ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
320138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  builder()->BuildJSArrayHeader(array_object,
320238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                map,
320338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                NULL,  // set elements to empty fixed array
320438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                mode_,
320538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                kind_,
320638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                allocation_site_payload_,
320738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                length_field);
320838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
320938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  // Allocate and initialize the elements
321038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  elements_location_ = builder()->BuildAllocateElements(kind_, elements_size);
321138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
3212c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  builder()->BuildInitializeElementsHeader(elements_location_, kind_, capacity);
3213ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
321438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  // Set the elements
321538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  builder()->Add<HStoreNamedField>(
321638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      array_object, HObjectAccess::ForElementsPointer(), elements_location_);
321738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org
3218b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (fill_mode == FILL_WITH_HOLE) {
3219d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    builder()->BuildFillElementsWithHole(elements_location_, kind_,
3220ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org                                         graph()->GetConstant0(), capacity);
3221ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
3222ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
322338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  return array_object;
3224ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
3225ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3226ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
3227d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgHValue* HGraphBuilder::AddLoadJSBuiltin(Builtins::JavaScript builtin) {
322805150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org  HValue* global_object = Add<HLoadNamedField>(
322909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      context(), static_cast<HValue*>(NULL),
323009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
32310a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset(
3232e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org      GlobalObject::kBuiltinsOffset);
323309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  HValue* builtins = Add<HLoadNamedField>(
323409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      global_object, static_cast<HValue*>(NULL), access);
32350a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  HObjectAccess function_access = HObjectAccess::ForObservableJSObjectOffset(
32360a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org          JSBuiltinsObject::OffsetOfFunctionWithId(builtin));
323709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  return Add<HLoadNamedField>(
323809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      builtins, static_cast<HValue*>(NULL), function_access);
3239e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org}
3240e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
3241e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
3242c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.orgHOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info)
3243a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    : HGraphBuilder(info),
3244a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      function_state_(NULL),
3245f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      initial_function_state_(this, info, NORMAL_RETURN, 0),
3246ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      ast_context_(NULL),
3247ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      break_scope_(NULL),
3248ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      inlined_count_(0),
32495a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      globals_(10, info->zone()),
3250c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org      inline_bailout_(false),
3251c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org      osr_(new(info->zone()) HOsrBuilder(this)) {
3252ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // This is not initialized in the initializer list because the
3253ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // constructor for the initial state relies on function_state_ == NULL
3254ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // to know it's the initial state.
3255ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  function_state_= &initial_function_state_;
32566d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  InitializeAstVisitor(info->zone());
3257f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (FLAG_hydrogen_track_positions) {
325871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    SetSourcePosition(info->shared_info()->start_position());
325971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  }
3260ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org}
3261a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3262a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
3263a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHBasicBlock* HOptimizedGraphBuilder::CreateJoin(HBasicBlock* first,
3264a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                                HBasicBlock* second,
3265a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                                BailoutId join_id) {
32663a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  if (first == NULL) {
32675d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    return second;
32683a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  } else if (second == NULL) {
32695d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    return first;
32703a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  } else {
3271a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    HBasicBlock* join_block = graph()->CreateBasicBlock();
327271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    Goto(first, join_block);
327371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    Goto(second, join_block);
32743a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    join_block->SetJoinId(join_id);
32755d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org    return join_block;
3276a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
3277a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3278a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3279a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3280a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHBasicBlock* HOptimizedGraphBuilder::JoinContinue(IterationStatement* statement,
3281a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                                  HBasicBlock* exit_block,
3282a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                                  HBasicBlock* continue_block) {
3283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (continue_block != NULL) {
328471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    if (exit_block != NULL) Goto(exit_block, continue_block);
32853a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    continue_block->SetJoinId(statement->ContinueId());
32868f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    return continue_block;
3287a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
32888f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  return exit_block;
3289a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3290a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3291a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3292a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHBasicBlock* HOptimizedGraphBuilder::CreateLoop(IterationStatement* statement,
3293a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                                HBasicBlock* loop_entry,
3294a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                                HBasicBlock* body_exit,
3295a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                                HBasicBlock* loop_successor,
3296a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                                HBasicBlock* break_block) {
329771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  if (body_exit != NULL) Goto(body_exit, loop_entry);
32989ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  loop_entry->PostProcessLoopHeader(statement);
32998f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  if (break_block != NULL) {
330071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    if (loop_successor != NULL) Goto(loop_successor, break_block);
33018f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    break_block->SetJoinId(statement->ExitId());
33028f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    return break_block;
33038f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  }
33048f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  return loop_successor;
3305a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3306a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3307a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3308c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org// Build a new loop header block and set it as the current block.
3309c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgHBasicBlock* HOptimizedGraphBuilder::BuildLoopEntry() {
3310c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  HBasicBlock* loop_entry = CreateLoopHeaderBlock();
331171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  Goto(loop_entry);
3312c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  set_current_block(loop_entry);
3313c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  return loop_entry;
3314c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org}
3315c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org
3316c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org
3317c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgHBasicBlock* HOptimizedGraphBuilder::BuildLoopEntry(
3318c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org    IterationStatement* statement) {
3319c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  HBasicBlock* loop_entry = osr()->HasOsrEntryAt(statement)
3320c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org      ? osr()->BuildOsrLoopEntry(statement)
3321c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org      : BuildLoopEntry();
3322c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  return loop_entry;
3323c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org}
3324c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org
3325c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org
3326f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid HBasicBlock::FinishExit(HControlInstruction* instruction,
3327f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                             HSourcePosition position) {
332871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  Finish(instruction, position);
33295d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  ClearEnvironment();
3330a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3331a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3332a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
33335a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgHGraph::HGraph(CompilationInfo* info)
3334ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    : isolate_(info->isolate()),
3335ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      next_block_id_(0),
33364d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org      entry_block_(NULL),
33375a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      blocks_(8, info->zone()),
33385a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      values_(16, info->zone()),
33397028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      phi_list_(NULL),
334046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      uint32_instructions_(NULL),
3341c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org      osr_(NULL),
33425a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      info_(info),
33435a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      zone_(info->zone()),
334446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      is_recursive_(false),
334546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      use_optimistic_licm_(false),
3346906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      depends_on_empty_array_proto_elements_(false),
3347d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      type_change_checksum_(0),
3348ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org      maximum_environment_size_(0),
3349935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org      no_side_effects_scope_count_(0),
3350f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      disallow_adding_new_values_(false),
3351f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      next_inline_id_(0),
3352f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      inlined_functions_(5, info->zone()) {
3353a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (info->IsStub()) {
335409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    HydrogenCodeStub* stub = info->code_stub();
3355f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    CodeStubInterfaceDescriptor* descriptor = stub->GetInterfaceDescriptor();
3356a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    start_environment_ =
33576e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org        new(zone_) HEnvironment(zone_, descriptor->environment_length());
3358a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  } else {
3359f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    TraceInlinedFunction(info->shared_info(), HSourcePosition::Unknown());
3360a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    start_environment_ =
3361a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_);
3362a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
3363b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  start_environment_->set_ast_id(BailoutId::FunctionEntry());
33644d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  entry_block_ = CreateBasicBlock();
3365b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  entry_block_->SetInitialEnvironment(start_environment_);
3366a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3367a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3368a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3369a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgHBasicBlock* HGraph::CreateBasicBlock() {
337074f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  HBasicBlock* result = new(zone()) HBasicBlock(this);
33717028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  blocks_.Add(result, zone());
3372a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return result;
3373a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3374a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3375a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
33763d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.orgvoid HGraph::FinalizeUniqueness() {
337779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
33789af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  ASSERT(!OptimizingCompilerThread::IsOptimizerThread(isolate()));
3379e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  for (int i = 0; i < blocks()->length(); ++i) {
338093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org    for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) {
33813d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org      it.Current()->FinalizeUniqueness();
3382e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    }
3383e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
3384e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
3385e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
3386e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
3387f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgint HGraph::TraceInlinedFunction(
3388f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    Handle<SharedFunctionInfo> shared,
3389f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    HSourcePosition position) {
3390f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (!FLAG_hydrogen_track_positions) {
3391f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    return 0;
3392f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
3393f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
3394f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  int id = 0;
3395f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  for (; id < inlined_functions_.length(); id++) {
3396f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (inlined_functions_[id].shared().is_identical_to(shared)) {
3397f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      break;
3398f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    }
3399f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
3400f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
3401f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (id == inlined_functions_.length()) {
3402f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    inlined_functions_.Add(InlinedFunctionInfo(shared), zone());
3403f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
3404f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (!shared->script()->IsUndefined()) {
3405f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      Handle<Script> script(Script::cast(shared->script()));
3406f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      if (!script->source()->IsUndefined()) {
3407f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
3408f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        PrintF(tracing_scope.file(),
3409f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org               "--- FUNCTION SOURCE (%s) id{%d,%d} ---\n",
3410f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org               shared->DebugName()->ToCString().get(),
3411f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org               info()->optimization_id(),
3412f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org               id);
3413f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
3414f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        {
3415f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          ConsStringIteratorOp op;
3416f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          StringCharacterStream stream(String::cast(script->source()),
3417f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                       &op,
3418f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                       shared->start_position());
3419f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          // fun->end_position() points to the last character in the stream. We
3420f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          // need to compensate by adding one to calculate the length.
3421f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          int source_len =
3422f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org              shared->end_position() - shared->start_position() + 1;
3423f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          for (int i = 0; i < source_len; i++) {
3424f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org            if (stream.HasMore()) {
3425f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org              PrintF(tracing_scope.file(), "%c", stream.GetNext());
3426f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org            }
3427f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          }
3428f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        }
3429f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
3430f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        PrintF(tracing_scope.file(), "\n--- END ---\n");
3431f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      }
3432f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    }
3433f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
3434f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
3435f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  int inline_id = next_inline_id_++;
3436f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
3437f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (inline_id != 0) {
3438f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
3439f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    PrintF(tracing_scope.file(), "INLINE (%s) id{%d,%d} AS %d AT ",
3440f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org           shared->DebugName()->ToCString().get(),
3441f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org           info()->optimization_id(),
3442f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org           id,
3443f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org           inline_id);
3444f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    position.PrintTo(tracing_scope.file());
3445f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    PrintF(tracing_scope.file(), "\n");
3446f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
3447f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
3448f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  return inline_id;
3449f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
3450f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
3451f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
3452f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgint HGraph::SourcePositionToScriptPosition(HSourcePosition pos) {
3453f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (!FLAG_hydrogen_track_positions || pos.IsUnknown()) {
3454f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    return pos.raw();
3455f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
3456f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
3457f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  return inlined_functions_[pos.inlining_id()].start_position() +
3458f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      pos.position();
3459f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
3460f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
3461f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
34625a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// Block ordering was implemented with two mutually recursive methods,
34635a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// HGraph::Postorder and HGraph::PostorderLoopBlocks.
34645a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// The recursion could lead to stack overflow so the algorithm has been
34655a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// implemented iteratively.
34665a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// At a high level the algorithm looks like this:
34675a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//
34685a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// Postorder(block, loop_header) : {
34695a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//   if (block has already been visited or is of another loop) return;
34705a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//   mark block as visited;
34715a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//   if (block is a loop header) {
34725a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//     VisitLoopMembers(block, loop_header);
34735a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//     VisitSuccessorsOfLoopHeader(block);
34745a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//   } else {
34755a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//     VisitSuccessors(block)
34765a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//   }
34775a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//   put block in result list;
34785a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// }
34795a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//
34805a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// VisitLoopMembers(block, outer_loop_header) {
34815a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//   foreach (block b in block loop members) {
34825a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//     VisitSuccessorsOfLoopMember(b, outer_loop_header);
34835a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//     if (b is loop header) VisitLoopMembers(b);
34845a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//   }
34855a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// }
34865a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//
34875a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// VisitSuccessorsOfLoopMember(block, outer_loop_header) {
34885a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//   foreach (block b in block successors) Postorder(b, outer_loop_header)
34895a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// }
34905a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//
34915a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// VisitSuccessorsOfLoopHeader(block) {
34925a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//   foreach (block b in block successors) Postorder(b, block)
34935a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// }
34945a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//
34955a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// VisitSuccessors(block, loop_header) {
34965a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//   foreach (block b in block successors) Postorder(b, loop_header)
34975a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// }
34985a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//
34995a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// The ordering is started calling Postorder(entry, NULL).
35005a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//
35015a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// Each instance of PostorderProcessor represents the "stack frame" of the
35025a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// recursion, and particularly keeps the state of the loop (iteration) of the
35035a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// "Visit..." function it represents.
35045a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// To recycle memory we keep all the frames in a double linked list but
35055a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org// this means that we cannot use constructors to initialize the frames.
35065a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org//
35075a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgclass PostorderProcessor : public ZoneObject {
35085a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org public:
35095a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Back link (towards the stack bottom).
35105a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  PostorderProcessor* parent() {return father_; }
35115a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Forward link (towards the stack top).
35125a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  PostorderProcessor* child() {return child_; }
35135a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  HBasicBlock* block() { return block_; }
35145a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  HLoopInformation* loop() { return loop_; }
35155a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  HBasicBlock* loop_header() { return loop_header_; }
3516a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
35175a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  static PostorderProcessor* CreateEntryProcessor(Zone* zone,
351854ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org                                                  HBasicBlock* block) {
35195a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    PostorderProcessor* result = new(zone) PostorderProcessor(NULL);
352054ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org    return result->SetupSuccessors(zone, block, NULL);
35215a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
3522a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
35235a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  PostorderProcessor* PerformStep(Zone* zone,
35245a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                                  ZoneList<HBasicBlock*>* order) {
35255a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    PostorderProcessor* next =
352654ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org        PerformNonBacktrackingStep(zone, order);
35275a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    if (next != NULL) {
35285a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      return next;
35295a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    } else {
353054ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org      return Backtrack(zone, order);
35315a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    }
35325a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
3533a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
35345a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org private:
35355a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  explicit PostorderProcessor(PostorderProcessor* father)
35365a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      : father_(father), child_(NULL), successor_iterator(NULL) { }
35375a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
35385a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Each enum value states the cycle whose state is kept by this instance.
35395a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  enum LoopKind {
35405a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    NONE,
35415a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    SUCCESSORS,
35425a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    SUCCESSORS_OF_LOOP_HEADER,
35435a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    LOOP_MEMBERS,
35445a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    SUCCESSORS_OF_LOOP_MEMBER
35455a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  };
35465a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
35475a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Each "Setup..." method is like a constructor for a cycle state.
35485a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  PostorderProcessor* SetupSuccessors(Zone* zone,
35495a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                                      HBasicBlock* block,
355054ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org                                      HBasicBlock* loop_header) {
355154ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org    if (block == NULL || block->IsOrdered() ||
35525a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        block->parent_loop_header() != loop_header) {
35535a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      kind_ = NONE;
35545a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      block_ = NULL;
35555a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      loop_ = NULL;
35565a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      loop_header_ = NULL;
35575a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      return this;
35585a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    } else {
35595a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      block_ = block;
35605a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      loop_ = NULL;
356154ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org      block->MarkAsOrdered();
35625a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
35635a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      if (block->IsLoopHeader()) {
35645a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        kind_ = SUCCESSORS_OF_LOOP_HEADER;
35655a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        loop_header_ = block;
35665a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        InitializeSuccessors();
35675a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        PostorderProcessor* result = Push(zone);
35685a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        return result->SetupLoopMembers(zone, block, block->loop_information(),
35695a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                                        loop_header);
35705a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      } else {
35715a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        ASSERT(block->IsFinished());
35725a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        kind_ = SUCCESSORS;
35735a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        loop_header_ = loop_header;
35745a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        InitializeSuccessors();
35755a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        return this;
35765a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      }
35775a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    }
3578a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
3579a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
35805a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  PostorderProcessor* SetupLoopMembers(Zone* zone,
35815a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                                       HBasicBlock* block,
35825a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                                       HLoopInformation* loop,
35835a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                                       HBasicBlock* loop_header) {
35845a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    kind_ = LOOP_MEMBERS;
35855a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    block_ = block;
35865a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    loop_ = loop;
35875a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    loop_header_ = loop_header;
35885a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    InitializeLoopMembers();
35895a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    return this;
35905a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
3591a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
35925a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  PostorderProcessor* SetupSuccessorsOfLoopMember(
35935a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      HBasicBlock* block,
35945a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      HLoopInformation* loop,
35955a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      HBasicBlock* loop_header) {
35965a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    kind_ = SUCCESSORS_OF_LOOP_MEMBER;
35975a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    block_ = block;
35985a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    loop_ = loop;
35995a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    loop_header_ = loop_header;
36005a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    InitializeSuccessors();
36015a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    return this;
36025a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
36035a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
36045a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // This method "allocates" a new stack frame.
36055a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  PostorderProcessor* Push(Zone* zone) {
36065a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    if (child_ == NULL) {
36075a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      child_ = new(zone) PostorderProcessor(this);
36085a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    }
36095a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    return child_;
36105a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
36115a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
36125a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  void ClosePostorder(ZoneList<HBasicBlock*>* order, Zone* zone) {
36135a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    ASSERT(block_->end()->FirstSuccessor() == NULL ||
36145a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org           order->Contains(block_->end()->FirstSuccessor()) ||
36155a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org           block_->end()->FirstSuccessor()->IsLoopHeader());
36165a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    ASSERT(block_->end()->SecondSuccessor() == NULL ||
36175a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org           order->Contains(block_->end()->SecondSuccessor()) ||
36185a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org           block_->end()->SecondSuccessor()->IsLoopHeader());
36195a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    order->Add(block_, zone);
36205a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
36215a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
36225a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // This method is the basic block to walk up the stack.
36235a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  PostorderProcessor* Pop(Zone* zone,
36245a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                          ZoneList<HBasicBlock*>* order) {
36255a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    switch (kind_) {
36265a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      case SUCCESSORS:
36275a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      case SUCCESSORS_OF_LOOP_HEADER:
36285a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        ClosePostorder(order, zone);
36295a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        return father_;
36305a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      case LOOP_MEMBERS:
36315a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        return father_;
36325a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      case SUCCESSORS_OF_LOOP_MEMBER:
36335a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        if (block()->IsLoopHeader() && block() != loop_->loop_header()) {
36345a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org          // In this case we need to perform a LOOP_MEMBERS cycle so we
36355a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org          // initialize it and return this instead of father.
36365a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org          return SetupLoopMembers(zone, block(),
36375a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                                  block()->loop_information(), loop_header_);
36385a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        } else {
36395a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org          return father_;
36405a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        }
36415a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      case NONE:
36425a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        return father_;
36436d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    }
36445a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    UNREACHABLE();
36455a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    return NULL;
36465a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
36475a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
36485a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // Walks up the stack.
36495a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  PostorderProcessor* Backtrack(Zone* zone,
36505a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                                ZoneList<HBasicBlock*>* order) {
365154ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org    PostorderProcessor* parent = Pop(zone, order);
36525a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    while (parent != NULL) {
36535a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      PostorderProcessor* next =
365454ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org          parent->PerformNonBacktrackingStep(zone, order);
36555a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      if (next != NULL) {
36565a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        return next;
36575a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      } else {
365854ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org        parent = parent->Pop(zone, order);
36595a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      }
3660a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
36615a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    return NULL;
36625a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
36635a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
36645a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  PostorderProcessor* PerformNonBacktrackingStep(
36655a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      Zone* zone,
36665a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      ZoneList<HBasicBlock*>* order) {
36675a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    HBasicBlock* next_block;
36685a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    switch (kind_) {
36695a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      case SUCCESSORS:
36705a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        next_block = AdvanceSuccessors();
36715a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        if (next_block != NULL) {
36725a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org          PostorderProcessor* result = Push(zone);
367354ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org          return result->SetupSuccessors(zone, next_block, loop_header_);
36745a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        }
36755a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        break;
36765a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      case SUCCESSORS_OF_LOOP_HEADER:
36775a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        next_block = AdvanceSuccessors();
36785a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        if (next_block != NULL) {
36795a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org          PostorderProcessor* result = Push(zone);
368054ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org          return result->SetupSuccessors(zone, next_block, block());
36815a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        }
36825a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        break;
36835a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      case LOOP_MEMBERS:
36845a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        next_block = AdvanceLoopMembers();
36855a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        if (next_block != NULL) {
36865a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org          PostorderProcessor* result = Push(zone);
36875a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org          return result->SetupSuccessorsOfLoopMember(next_block,
36885a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                                                     loop_, loop_header_);
36895a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        }
36905a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        break;
36915a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      case SUCCESSORS_OF_LOOP_MEMBER:
36925a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        next_block = AdvanceSuccessors();
36935a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        if (next_block != NULL) {
36945a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org          PostorderProcessor* result = Push(zone);
369554ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org          return result->SetupSuccessors(zone, next_block, loop_header_);
36965a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        }
36975a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        break;
36985a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      case NONE:
36995a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        return NULL;
37005a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    }
37015a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    return NULL;
3702a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
3703a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
37045a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // The following two methods implement a "foreach b in successors" cycle.
37055a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  void InitializeSuccessors() {
37065a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    loop_index = 0;
37075a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    loop_length = 0;
37085a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    successor_iterator = HSuccessorIterator(block_->end());
37095a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
3710a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
37115a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  HBasicBlock* AdvanceSuccessors() {
37125a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    if (!successor_iterator.Done()) {
37135a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      HBasicBlock* result = successor_iterator.Current();
37145a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      successor_iterator.Advance();
37155a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      return result;
37166d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    }
37175a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    return NULL;
37185a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
37195a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
37205a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // The following two methods implement a "foreach b in loop members" cycle.
37215a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  void InitializeLoopMembers() {
37225a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    loop_index = 0;
37235a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    loop_length = loop_->blocks()->length();
37245a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
37255a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
37265a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  HBasicBlock* AdvanceLoopMembers() {
37275a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    if (loop_index < loop_length) {
37285a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      HBasicBlock* result = loop_->blocks()->at(loop_index);
37295a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      loop_index++;
37305a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      return result;
37315a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org    } else {
37325a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      return NULL;
37336d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    }
3734a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
37355a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
37365a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  LoopKind kind_;
37375a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  PostorderProcessor* father_;
37385a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  PostorderProcessor* child_;
37395a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  HLoopInformation* loop_;
37405a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  HBasicBlock* block_;
37415a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  HBasicBlock* loop_header_;
37425a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  int loop_index;
37435a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  int loop_length;
37445a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  HSuccessorIterator successor_iterator;
37455a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org};
37465a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
37475a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
37485a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgvoid HGraph::OrderBlocks() {
37491510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  CompilationPhase phase("H_Block ordering", info());
37505a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
375154ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org#ifdef DEBUG
375254ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org  // Initially the blocks must not be ordered.
375354ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org  for (int i = 0; i < blocks_.length(); ++i) {
375454ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org    ASSERT(!blocks_[i]->IsOrdered());
37555a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
375654ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org#endif
375754ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org
375854ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org  PostorderProcessor* postorder =
375954ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org      PostorderProcessor::CreateEntryProcessor(zone(), blocks_[0]);
37605a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  blocks_.Rewind(0);
376154ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org  while (postorder) {
376254ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org    postorder = postorder->PerformStep(zone(), &blocks_);
376354ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org  }
376454ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org
376554ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org#ifdef DEBUG
376654ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org  // Now all blocks must be marked as ordered.
376754ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org  for (int i = 0; i < blocks_.length(); ++i) {
376854ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org    ASSERT(blocks_[i]->IsOrdered());
376954ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org  }
377054ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org#endif
377154ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org
377254ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org  // Reverse block list and assign block IDs.
377354ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org  for (int i = 0, j = blocks_.length(); --j >= i; ++i) {
377454ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org    HBasicBlock* bi = blocks_[i];
377554ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org    HBasicBlock* bj = blocks_[j];
377654ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org    bi->set_block_id(j);
377754ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org    bj->set_block_id(i);
377854ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org    blocks_[i] = bj;
377954ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org    blocks_[j] = bi;
37805a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
3781a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3782a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3783a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3784a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HGraph::AssignDominators() {
37859a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org  HPhase phase("H_Assign dominators", this);
3786a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < blocks_.length(); ++i) {
378778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    HBasicBlock* block = blocks_[i];
378878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    if (block->IsLoopHeader()) {
37892c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      // Only the first predecessor of a loop header is from outside the loop.
37902c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org      // All others are back edges, and thus cannot dominate the loop header.
379178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      block->AssignCommonDominator(block->predecessors()->first());
379278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      block->AssignLoopSuccessorDominators();
3793a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    } else {
3794c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org      for (int j = blocks_[i]->predecessors()->length() - 1; j >= 0; --j) {
3795a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        blocks_[i]->AssignCommonDominator(blocks_[i]->predecessors()->at(j));
3796a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
3797a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
3798a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
37992c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org}
38006d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
380146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
3802c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool HGraph::CheckArgumentsPhiUses() {
3803d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org  int block_count = blocks_.length();
3804d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org  for (int i = 0; i < block_count; ++i) {
3805d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    for (int j = 0; j < blocks_[i]->phis()->length(); ++j) {
3806d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org      HPhi* phi = blocks_[i]->phis()->at(j);
3807d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org      // We don't support phi uses of arguments for now.
3808d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org      if (phi->CheckFlag(HValue::kIsArguments)) return false;
3809d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org    }
3810d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org  }
3811d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org  return true;
3812d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org}
3813d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org
3814d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org
3815c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool HGraph::CheckConstPhiUses() {
38164d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  int block_count = blocks_.length();
38174d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  for (int i = 0; i < block_count; ++i) {
38184d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    for (int j = 0; j < blocks_[i]->phis()->length(); ++j) {
38194d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org      HPhi* phi = blocks_[i]->phis()->at(j);
3820d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org      // Check for the hole value (from an uninitialized const).
3821d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org      for (int k = 0; k < phi->OperandCount(); k++) {
3822d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org        if (phi->OperandAt(k) == GetConstantHole()) return false;
3823d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org      }
3824a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
3825a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
3826a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return true;
3827a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3828a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3829a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3830c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid HGraph::CollectPhis() {
3831c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int block_count = blocks_.length();
38327028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  phi_list_ = new(zone()) ZoneList<HPhi*>(block_count, zone());
3833c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for (int i = 0; i < block_count; ++i) {
3834c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    for (int j = 0; j < blocks_[i]->phis()->length(); ++j) {
3835c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      HPhi* phi = blocks_[i]->phis()->at(j);
38367028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      phi_list_->Add(phi, zone());
3837c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
3838c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
3839c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
3840c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3841c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
38428f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org// Implementation of utility class to encapsulate the translation state for
38438f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org// a (possibly inlined) function.
3844a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgFunctionState::FunctionState(HOptimizedGraphBuilder* owner,
38458f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                             CompilationInfo* info,
3846f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                             InliningKind inlining_kind,
3847f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                             int inlining_id)
38488f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    : owner_(owner),
38498f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      compilation_info_(info),
38508f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      call_context_(NULL),
3851471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      inlining_kind_(inlining_kind),
38528f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      function_return_(NULL),
38538f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      test_context_(NULL),
385428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org      entry_(NULL),
3855b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      arguments_object_(NULL),
385628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org      arguments_elements_(NULL),
3857f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      inlining_id_(inlining_id),
3858f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      outer_source_position_(HSourcePosition::Unknown()),
38598f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      outer_(owner->function_state()) {
38608f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  if (outer_ != NULL) {
38618f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    // State for an inline function.
38628f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    if (owner->ast_context()->IsTest()) {
38638f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      HBasicBlock* if_true = owner->graph()->CreateBasicBlock();
38648f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      HBasicBlock* if_false = owner->graph()->CreateBasicBlock();
3865d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      if_true->MarkAsInlineReturnTarget(owner->current_block());
3866d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      if_false->MarkAsInlineReturnTarget(owner->current_block());
3867471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      TestContext* outer_test_context = TestContext::cast(owner->ast_context());
3868471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      Expression* cond = outer_test_context->condition();
38698f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      // The AstContext constructor pushed on the context stack.  This newed
38708f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      // instance is the reason that AstContext can't be BASE_EMBEDDED.
3871c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      test_context_ = new TestContext(owner, cond, if_true, if_false);
38728f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    } else {
38738f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      function_return_ = owner->graph()->CreateBasicBlock();
3874d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      function_return()->MarkAsInlineReturnTarget(owner->current_block());
38758f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    }
38768f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    // Set this after possibly allocating a new TestContext above.
38778f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    call_context_ = owner->ast_context();
38788f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  }
38798f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
38808f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // Push on the state stack.
38818f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  owner->set_function_state(this);
3882f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
3883f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (FLAG_hydrogen_track_positions) {
3884f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    outer_source_position_ = owner->source_position();
3885f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    owner->EnterInlinedSource(
3886f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      info->shared_info()->start_position(),
3887f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      inlining_id);
3888f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    owner->SetSourcePosition(info->shared_info()->start_position());
3889f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
38908f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org}
38918f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
38928f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
38938f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.orgFunctionState::~FunctionState() {
38948f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  delete test_context_;
38958f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  owner_->set_function_state(outer_);
3896f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
3897f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (FLAG_hydrogen_track_positions) {
3898f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    owner_->set_source_position(outer_source_position_);
3899f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    owner_->EnterInlinedSource(
3900f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      outer_->compilation_info()->shared_info()->start_position(),
3901f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      outer_->inlining_id());
3902f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
39038f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org}
39048f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
39058f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
3906a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Implementation of utility classes to represent an expression's context in
3907a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// the AST.
3908a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgAstContext::AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind)
3909c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    : owner_(owner),
3910c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      kind_(kind),
3911c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      outer_(owner->ast_context()),
3912c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      for_typeof_(false) {
3913a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  owner->set_ast_context(this);  // Push.
39145f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org#ifdef DEBUG
3915967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  ASSERT(owner->environment()->frame_type() == JS_FUNCTION);
39165d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  original_length_ = owner->environment()->length();
39175f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org#endif
3918a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3919a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3920a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3921a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgAstContext::~AstContext() {
3922a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  owner_->set_ast_context(outer_);  // Pop.
3923a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
3924a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
3925a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
39265f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgEffectContext::~EffectContext() {
39275f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  ASSERT(owner()->HasStackOverflow() ||
39283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org         owner()->current_block() == NULL ||
3929659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org         (owner()->environment()->length() == original_length_ &&
3930967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org          owner()->environment()->frame_type() == JS_FUNCTION));
39315f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
39325f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
39335f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
39345f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgValueContext::~ValueContext() {
39355f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  ASSERT(owner()->HasStackOverflow() ||
39363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org         owner()->current_block() == NULL ||
3937659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org         (owner()->environment()->length() == original_length_ + 1 &&
3938967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org          owner()->environment()->frame_type() == JS_FUNCTION));
39395f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
39405f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
39415f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
39425f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvoid EffectContext::ReturnValue(HValue* value) {
39435f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // The value is simply ignored.
39445f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
39455f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
39465f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
39475f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvoid ValueContext::ReturnValue(HValue* value) {
39485f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // The value is tracked in the bailout environment, and communicated
39495f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // through the environment as the result of the expression.
39508e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  if (!arguments_allowed() && value->CheckFlag(HValue::kIsArguments)) {
3951594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    owner()->Bailout(kBadValueContextForArgumentsValue);
39528e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  }
39535f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  owner()->Push(value);
39545f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
39555f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
39565f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
39575f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvoid TestContext::ReturnValue(HValue* value) {
39585f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  BuildBranch(value);
39595f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
39605f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
39615f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
3962471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid EffectContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
39634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  ASSERT(!instr->IsControlInstruction());
39645f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  owner()->AddInstruction(instr);
3965fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  if (instr->HasObservableSideEffects()) {
3966c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    owner()->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
3967fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  }
39685f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
39695f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
39705f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
3971471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid EffectContext::ReturnControl(HControlInstruction* instr,
3972471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                                  BailoutId ast_id) {
3973c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(!instr->HasObservableSideEffects());
39744f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock();
39754f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock();
39764f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  instr->SetSuccessorAt(0, empty_true);
39774f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  instr->SetSuccessorAt(1, empty_false);
397871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  owner()->FinishCurrentBlock(instr);
39794f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  HBasicBlock* join = owner()->CreateJoin(empty_true, empty_false, ast_id);
39804f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  owner()->set_current_block(join);
39814f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org}
39824f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
39834f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
3984b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgvoid EffectContext::ReturnContinuation(HIfContinuation* continuation,
3985b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org                                       BailoutId ast_id) {
3986b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  HBasicBlock* true_branch = NULL;
3987b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  HBasicBlock* false_branch = NULL;
398871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  continuation->Continue(&true_branch, &false_branch);
3989b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  if (!continuation->IsTrueReachable()) {
3990b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    owner()->set_current_block(false_branch);
3991b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  } else if (!continuation->IsFalseReachable()) {
3992b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    owner()->set_current_block(true_branch);
3993b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  } else {
3994b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    HBasicBlock* join = owner()->CreateJoin(true_branch, false_branch, ast_id);
3995b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    owner()->set_current_block(join);
3996b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  }
3997b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org}
3998b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
3999b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
4000471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
40014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  ASSERT(!instr->IsControlInstruction());
40028e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) {
4003594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return owner()->Bailout(kBadValueContextForArgumentsObjectValue);
40048e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  }
40055f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  owner()->AddInstruction(instr);
40065f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  owner()->Push(instr);
4007fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  if (instr->HasObservableSideEffects()) {
4008c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    owner()->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
4009fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  }
40105f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
40115f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
40125f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4013471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid ValueContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) {
4014c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(!instr->HasObservableSideEffects());
40154f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) {
4016594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return owner()->Bailout(kBadValueContextForArgumentsObjectValue);
40174f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
40184f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  HBasicBlock* materialize_false = owner()->graph()->CreateBasicBlock();
40194f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  HBasicBlock* materialize_true = owner()->graph()->CreateBasicBlock();
40204f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  instr->SetSuccessorAt(0, materialize_true);
40214f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  instr->SetSuccessorAt(1, materialize_false);
402271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  owner()->FinishCurrentBlock(instr);
40234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  owner()->set_current_block(materialize_true);
40244f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  owner()->Push(owner()->graph()->GetConstantTrue());
40254f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  owner()->set_current_block(materialize_false);
40264f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  owner()->Push(owner()->graph()->GetConstantFalse());
40274f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  HBasicBlock* join =
40284f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    owner()->CreateJoin(materialize_true, materialize_false, ast_id);
40294f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  owner()->set_current_block(join);
40304f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org}
40314f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
40324f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
4033b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgvoid ValueContext::ReturnContinuation(HIfContinuation* continuation,
4034b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org                                      BailoutId ast_id) {
4035b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  HBasicBlock* materialize_true = NULL;
4036b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  HBasicBlock* materialize_false = NULL;
403771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  continuation->Continue(&materialize_true, &materialize_false);
4038b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  if (continuation->IsTrueReachable()) {
4039b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    owner()->set_current_block(materialize_true);
4040b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    owner()->Push(owner()->graph()->GetConstantTrue());
4041b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    owner()->set_current_block(materialize_true);
4042b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  }
4043b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  if (continuation->IsFalseReachable()) {
4044b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    owner()->set_current_block(materialize_false);
4045b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    owner()->Push(owner()->graph()->GetConstantFalse());
4046b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    owner()->set_current_block(materialize_false);
4047b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  }
4048b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  if (continuation->TrueAndFalseReachable()) {
4049b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    HBasicBlock* join =
4050b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org        owner()->CreateJoin(materialize_true, materialize_false, ast_id);
4051b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    owner()->set_current_block(join);
4052b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  }
4053b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org}
4054b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
4055b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
4056471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
40574f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  ASSERT(!instr->IsControlInstruction());
4058a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  HOptimizedGraphBuilder* builder = owner();
40595f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  builder->AddInstruction(instr);
40605f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // We expect a simulate after every expression with side effects, though
40615f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // this one isn't actually needed (and wouldn't work if it were targeted).
4062c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (instr->HasObservableSideEffects()) {
40635f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    builder->Push(instr);
4064c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    builder->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
40655f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    builder->Pop();
40665f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  }
40675f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  BuildBranch(instr);
40685f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
40695f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
40705f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4071471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid TestContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) {
4072c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(!instr->HasObservableSideEffects());
40734f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock();
40744f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock();
40754f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  instr->SetSuccessorAt(0, empty_true);
40764f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  instr->SetSuccessorAt(1, empty_false);
407771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  owner()->FinishCurrentBlock(instr);
407871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  owner()->Goto(empty_true, if_true(), owner()->function_state());
407971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  owner()->Goto(empty_false, if_false(), owner()->function_state());
40804f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  owner()->set_current_block(NULL);
40814f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org}
40824f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
40834f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
4084b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.orgvoid TestContext::ReturnContinuation(HIfContinuation* continuation,
4085b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org                                     BailoutId ast_id) {
4086b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  HBasicBlock* true_branch = NULL;
4087b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  HBasicBlock* false_branch = NULL;
408871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  continuation->Continue(&true_branch, &false_branch);
4089b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  if (continuation->IsTrueReachable()) {
409071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    owner()->Goto(true_branch, if_true(), owner()->function_state());
4091b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  }
4092b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  if (continuation->IsFalseReachable()) {
409371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    owner()->Goto(false_branch, if_false(), owner()->function_state());
4094b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  }
4095b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  owner()->set_current_block(NULL);
4096b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org}
4097b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
4098b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org
40995f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvoid TestContext::BuildBranch(HValue* value) {
41005f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // We expect the graph to be in edge-split form: there is no edge that
41015f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // connects a branch node to a join node.  We conservatively ensure that
41025f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // property by always adding an empty block on the outgoing edges of this
41035f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // branch.
4104a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  HOptimizedGraphBuilder* builder = owner();
41054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if (value != NULL && value->CheckFlag(HValue::kIsArguments)) {
4106594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    builder->Bailout(kArgumentsObjectValueInATestContext);
41078e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  }
4108c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  ToBooleanStub::Types expected(condition()->to_boolean_types());
4109cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  ReturnControl(owner()->New<HBranch>(value, expected), BailoutId::None());
41105f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
41115f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4112a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4113a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org// HOptimizedGraphBuilder infrastructure for bailing out and checking bailouts.
4114160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org#define CHECK_BAILOUT(call)                     \
4115a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  do {                                          \
4116160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    call;                                       \
4117a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (HasStackOverflow()) return;             \
4118a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } while (false)
4119a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4120a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4121160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org#define CHECK_ALIVE(call)                                       \
41225f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  do {                                                          \
4123160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    call;                                                       \
4124160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    if (HasStackOverflow() || current_block() == NULL) return;  \
41255f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  } while (false)
41265f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
41275f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4128b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org#define CHECK_ALIVE_OR_RETURN(call, value)                            \
4129b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  do {                                                                \
4130b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    call;                                                             \
4131b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    if (HasStackOverflow() || current_block() == NULL) return value;  \
4132b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  } while (false)
4133b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
4134b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
4135594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid HOptimizedGraphBuilder::Bailout(BailoutReason reason) {
413641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  current_info()->set_bailout_reason(reason);
4137a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SetStackOverflow();
4138a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4139a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4140a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4141a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitForEffect(Expression* expr) {
41425f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  EffectContext for_effect(this);
41435f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  Visit(expr);
4144a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4145a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4146a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4147a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitForValue(Expression* expr,
4148a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                           ArgumentsAllowedFlag flag) {
41498e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  ValueContext for_value(this, flag);
41505f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  Visit(expr);
41515f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
41525f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
41535f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4154a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitForTypeOf(Expression* expr) {
41558e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED);
4156c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  for_value.set_for_typeof(true);
4157c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  Visit(expr);
4158c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org}
4159c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
4160c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
4161a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitForControl(Expression* expr,
4162a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                             HBasicBlock* true_block,
4163a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                             HBasicBlock* false_block) {
4164c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  TestContext for_test(this, expr, true_block, false_block);
41655f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  Visit(expr);
4166a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4167a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4168a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4169a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitExpressions(
4170a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    ZoneList<Expression*>* exprs) {
41713a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  for (int i = 0; i < exprs->length(); ++i) {
4172160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    CHECK_ALIVE(VisitForValue(exprs->at(i)));
4173a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
4174a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4175a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4176a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4177a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgbool HOptimizedGraphBuilder::BuildGraph() {
417841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  if (current_info()->function()->is_generator()) {
4179594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Bailout(kFunctionIsAGenerator);
4180f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    return false;
4181f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  }
418241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  Scope* scope = current_info()->scope();
4183a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (scope->HasIllegalRedeclaration()) {
4184594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Bailout(kFunctionWithIllegalRedeclaration);
4185a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return false;
4186a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
4187a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (scope->calls_eval()) {
4188594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    Bailout(kFunctionCallsEval);
4189a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return false;
4190a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
4191a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  SetUpScope(scope);
4192a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
4193a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Add an edge to the body entry.  This is warty: the graph's start
4194a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // environment will be used by the Lithium translation as the initial
4195a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // environment on graph entry, but it has now been mutated by the
4196a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Hydrogen translation of the instructions in the start block.  This
4197a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // environment uses values which have not been defined yet.  These
4198a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Hydrogen instructions will then be replayed by the Lithium
4199a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // translation, so they cannot have an environment effect.  The edge to
4200a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // the body's entry block (along with some special logic for the start
4201a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // block in HInstruction::InsertAfter) seals the start block from
4202a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // getting unwanted instructions inserted.
4203a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  //
4204a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // TODO(kmillikin): Fix this.  Stop mutating the initial environment.
4205a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Make the Hydrogen instructions in the initial block into Hydrogen
4206a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // values (but not instructions), present in the initial environment and
4207a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // not replayed by the Lithium translation.
4208a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  HEnvironment* initial_env = environment()->CopyWithoutHistory();
4209b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  HBasicBlock* body_entry = CreateBasicBlock(initial_env);
421071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  Goto(body_entry);
4211a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  body_entry->SetJoinId(BailoutId::FunctionEntry());
4212a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  set_current_block(body_entry);
4213a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
4214a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Handle implicit declaration of the function name in named function
4215a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // expressions before other declarations.
4216a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (scope->is_function_scope() && scope->function() != NULL) {
4217a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    VisitVariableDeclaration(scope->function());
4218a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
4219a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  VisitDeclarations(scope->declarations());
4220c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  Add<HSimulate>(BailoutId::Declarations());
4221a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
42228e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  Add<HStackCheck>(HStackCheck::kFunctionEntry);
422332280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org
422441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  VisitStatements(current_info()->function()->body());
4225a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (HasStackOverflow()) return false;
422628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
4227a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (current_block() != NULL) {
4228c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    Add<HReturn>(graph()->GetConstantUndefined());
4229a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    set_current_block(NULL);
42305323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org  }
42315323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org
4232a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // If the checksum of the number of type info changes is the same as the
4233a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // last time this function was compiled, then this recompile is likely not
4234a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // due to missing/inadequate type feedback, but rather too aggressive
4235a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // optimization. Disable optimistic LICM in that case.
423641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  Handle<Code> unoptimized_code(current_info()->shared_info()->code());
4237a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  ASSERT(unoptimized_code->kind() == Code::FUNCTION);
4238a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  Handle<TypeFeedbackInfo> type_info(
4239a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      TypeFeedbackInfo::cast(unoptimized_code->type_feedback_info()));
4240a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  int checksum = type_info->own_type_change_checksum();
4241a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  int composite_checksum = graph()->update_type_change_checksum(checksum);
4242a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  graph()->set_use_optimistic_licm(
4243a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      !type_info->matches_inlined_type_change_checksum(composite_checksum));
4244a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  type_info->set_inlined_type_change_checksum(composite_checksum);
4245a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
4246c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  // Perform any necessary OSR-specific cleanups or changes to the graph.
4247c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  osr()->FinishGraph();
4248c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org
4249a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  return true;
42505323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org}
425132280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org
4252a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
4253594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgbool HGraph::Optimize(BailoutReason* bailout_reason) {
425428583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  OrderBlocks();
425528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  AssignDominators();
4256c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
42577c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  // We need to create a HConstant "zero" now so that GVN will fold every
42587c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  // zero-valued constant in the graph together.
42597c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  // The constant is needed to make idef-based bounds check work: the pass
42607c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  // evaluates relations with "zero" and that zero cannot be created after GVN.
42617c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  GetConstant0();
42627c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
4263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#ifdef DEBUG
4264c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Do a full verify after building the graph and computing dominators.
426528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  Verify(true);
4266c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif
4267c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
42681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (FLAG_analyze_environment_liveness && maximum_environment_size() != 0) {
42691510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Run<HEnvironmentLivenessAnalysisPhase>();
4270d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  }
4271d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
427228583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  if (!CheckConstPhiUses()) {
4273594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    *bailout_reason = kUnsupportedPhiUseOfConstVariable;
427428583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    return false;
4275d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org  }
4276e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  Run<HRedundantPhiEliminationPhase>();
427728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  if (!CheckArgumentsPhiUses()) {
4278594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    *bailout_reason = kUnsupportedPhiUseOfArguments;
427928583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    return false;
4280a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
42814e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
4282d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  // Find and mark unreachable code to simplify optimizations, especially gvn,
4283d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  // where unreachable code could unnecessarily defeat LICM.
4284d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  Run<HMarkUnreachableBlocksPhase>();
4285d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
4286e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>();
4287594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (FLAG_use_escape_analysis) Run<HEscapeAnalysisPhase>();
4288594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
4289528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (FLAG_load_elimination) Run<HLoadEliminationPhase>();
4290528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
429128583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  CollectPhis();
4292a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4293c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  if (has_osr()) osr()->FinishOsrValues();
42942c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
42951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Run<HInferRepresentationPhase>();
4296a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4297fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  // Remove HSimulate instructions that have turned out not to be needed
4298fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  // after all by folding them into the following HSimulate.
4299fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  // This must happen after inferring representations.
4300169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  Run<HMergeRemovableSimulatesPhase>();
4301fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
4302d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  Run<HMarkDeoptimizeOnUndefinedPhase>();
4303bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  Run<HRepresentationChangesPhase>();
4304a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4305e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  Run<HInferTypesPhase>();
430646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
430746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Must be performed before canonicalization to ensure that Canonicalize
430846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // will not remove semantically meaningful ToInt32 operations e.g. BIT_OR with
430946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // zero.
431093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  if (FLAG_opt_safe_uint32_operations) Run<HUint32AnalysisPhase>();
431146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
4312169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  if (FLAG_use_canonicalizing) Run<HCanonicalizePhase>();
4313a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
43141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (FLAG_use_gvn) Run<HGlobalValueNumberingPhase>();
4315a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4316cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  if (FLAG_check_elimination) Run<HCheckEliminationPhase>();
4317cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org
4318b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org  if (FLAG_store_elimination) Run<HStoreEliminationPhase>();
4319b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org
4320bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  Run<HRangeAnalysisPhase>();
4321c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org
4322c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  Run<HComputeChangeUndefinedToNaN>();
4323ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org
4324ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  // Eliminate redundant stack checks on backwards branches.
4325e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  Run<HStackCheckEliminationPhase>();
4326ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org
4327cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  if (FLAG_array_bounds_checks_elimination) Run<HBoundsCheckEliminationPhase>();
4328cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  if (FLAG_array_bounds_checks_hoisting) Run<HBoundsCheckHoistingPhase>();
4329169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  if (FLAG_array_index_dehoisting) Run<HDehoistIndexComputationsPhase>();
4330e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>();
43316d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
4332068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  RestoreActualValues();
4333068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org
4334d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  // Find unreachable code a second time, GVN and other optimizations may have
4335d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  // made blocks unreachable that were previously reachable.
4336d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  Run<HMarkUnreachableBlocksPhase>();
4337d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
433828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  return true;
4339a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4340a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4341a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4342068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.orgvoid HGraph::RestoreActualValues() {
4343068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  HPhase phase("H_Restore actual values", this);
4344068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org
4345068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  for (int block_index = 0; block_index < blocks()->length(); block_index++) {
4346068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org    HBasicBlock* block = blocks()->at(block_index);
4347068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org
4348068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org#ifdef DEBUG
4349068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org    for (int i = 0; i < block->phis()->length(); i++) {
4350068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org      HPhi* phi = block->phis()->at(i);
4351068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org      ASSERT(phi->ActualValue() == phi);
4352068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org    }
4353068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org#endif
4354068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org
435593a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org    for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
435693a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org      HInstruction* instruction = it.Current();
435705150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org      if (instruction->ActualValue() == instruction) continue;
435805150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org      if (instruction->CheckFlag(HValue::kIsDead)) {
435905150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org        // The instruction was marked as deleted but left in the graph
436005150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org        // as a control flow dependency point for subsequent
436105150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org        // instructions.
436205150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org        instruction->DeleteAndReplaceWith(instruction->ActualValue());
436305150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org      } else {
43642e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        ASSERT(instruction->IsInformativeDefinition());
43652e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        if (instruction->IsPurelyInformativeDefinition()) {
43662e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          instruction->DeleteAndReplaceWith(instruction->RedefinedOperand());
43672e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        } else {
43682e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          instruction->ReplaceAllUsesWith(instruction->ActualValue());
43692e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        }
4370068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org      }
4371068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org    }
4372068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  }
4373068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org}
4374068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org
4375068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org
437626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.orgvoid HOptimizedGraphBuilder::PushArgumentsFromEnvironment(int count) {
43777028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  ZoneList<HValue*> arguments(count, zone());
4378496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  for (int i = 0; i < count; ++i) {
43797028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    arguments.Add(Pop(), zone());
4380a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
4381a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
43828d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  HPushArguments* push_args = New<HPushArguments>();
4383496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  while (!arguments.is_empty()) {
43848d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    push_args->AddInput(arguments.RemoveLast());
4385a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
4386011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org  AddInstruction(push_args);
438726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org}
438826ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org
438926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org
439026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.orgtemplate <class Instruction>
439126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.orgHInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) {
439226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  PushArgumentsFromEnvironment(call->argument_count());
43933a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  return call;
4394a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4395a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4396a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4397a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::SetUpScope(Scope* scope) {
4398d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // First special is HContext.
4399d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* context = Add<HContext>();
4400d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  environment()->BindContext(context);
4401d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
4402b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  // Create an arguments object containing the initial parameters.  Set the
4403b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  // initial values of parameters including "this" having parameter index 0.
440483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count());
4405b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  HArgumentsObject* arguments_object =
4406d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      New<HArgumentsObject>(environment()->parameter_count());
440783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  for (int i = 0; i < environment()->parameter_count(); ++i) {
44081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    HInstruction* parameter = Add<HParameter>(i);
4409b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    arguments_object->AddArgument(parameter, zone());
4410a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    environment()->Bind(i, parameter);
4411a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
4412b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  AddInstruction(arguments_object);
4413b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  graph()->SetArgumentsObject(arguments_object);
4414a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
441571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  HConstant* undefined_constant = graph()->GetConstantUndefined();
441683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Initialize specials and locals to undefined.
441783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  for (int i = environment()->parameter_count() + 1;
441883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org       i < environment()->length();
441983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org       ++i) {
4420a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    environment()->Bind(i, undefined_constant);
4421a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
4422a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4423a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Handle the arguments and arguments shadow variables specially (they do
4424a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // not have declarations).
4425a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (scope->arguments() != NULL) {
44267b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    if (!scope->arguments()->IsStackAllocated()) {
4427594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      return Bailout(kContextAllocatedArguments);
44283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    }
4429154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org
4430154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    environment()->Bind(scope->arguments(),
4431154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org                        graph()->GetArgumentsObject());
4432a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
4433a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4434a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4435a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4436a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) {
4437a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < statements->length(); i++) {
4438dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    Statement* stmt = statements->at(i);
4439dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    CHECK_ALIVE(Visit(stmt));
4440dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    if (stmt->IsJump()) break;
4441a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
4442a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4443a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4444a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4445a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitBlock(Block* stmt) {
4446160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
4447160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
4448160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
44491e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org
44501e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  Scope* outer_scope = scope();
44511e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  Scope* scope = stmt->scope();
44521e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  BreakAndContinueInfo break_info(stmt, outer_scope);
44531e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org
44548f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  { BreakAndContinueScope push(&break_info, this);
44551e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    if (scope != NULL) {
44561e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      // Load the function object.
44571e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      Scope* declaration_scope = scope->DeclarationScope();
44581e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      HInstruction* function;
44591e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      HValue* outer_context = environment()->context();
44601e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      if (declaration_scope->is_global_scope() ||
44611e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org          declaration_scope->is_eval_scope()) {
44621e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org        function = new(zone()) HLoadContextSlot(
44631e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org            outer_context, Context::CLOSURE_INDEX, HLoadContextSlot::kNoCheck);
44641e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      } else {
44651e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org        function = New<HThisFunction>();
44661e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      }
44671e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      AddInstruction(function);
44681e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      // Allocate a block context and store it to the stack frame.
44691e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      HInstruction* inner_context = Add<HAllocateBlockContext>(
44701e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org          outer_context, function, scope->GetScopeInfo());
44711e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      HInstruction* instr = Add<HStoreFrameContext>(inner_context);
44721e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      if (instr->HasObservableSideEffects()) {
44731e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org        AddSimulate(stmt->EntryId(), REMOVABLE_SIMULATE);
44741e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      }
44751e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      set_scope(scope);
44761e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      environment()->BindContext(inner_context);
44771e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      VisitDeclarations(scope->declarations());
44781e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      AddSimulate(stmt->DeclsId(), REMOVABLE_SIMULATE);
44791e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    }
4480160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    CHECK_BAILOUT(VisitStatements(stmt->statements()));
44818f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  }
44821e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  set_scope(outer_scope);
44831e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  if (scope != NULL && current_block() != NULL) {
44841e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    HValue* inner_context = environment()->context();
44851e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    HValue* outer_context = Add<HLoadNamedField>(
44861e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org        inner_context, static_cast<HValue*>(NULL),
44871e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org        HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX));
44881e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org
44891e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    HInstruction* instr = Add<HStoreFrameContext>(outer_context);
44901e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    if (instr->HasObservableSideEffects()) {
44911e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      AddSimulate(stmt->ExitId(), REMOVABLE_SIMULATE);
44921e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    }
44931e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    environment()->BindContext(outer_context);
44941e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  }
44958f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  HBasicBlock* break_block = break_info.break_block();
44968f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  if (break_block != NULL) {
449771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    if (current_block() != NULL) Goto(break_block);
44988f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    break_block->SetJoinId(stmt->ExitId());
44998f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    set_current_block(break_block);
4500a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
4501a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4502a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4503a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4504a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitExpressionStatement(
4505a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    ExpressionStatement* stmt) {
4506160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
4507160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
4508160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
4509a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  VisitForEffect(stmt->expression());
4510a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4511a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4512a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4513a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) {
4514160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
4515160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
4516160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
4517a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4518a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4519a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4520a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitIfStatement(IfStatement* stmt) {
4521160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
4522160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
4523160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
4524a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (stmt->condition()->ToBooleanIsTrue()) {
4525c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    Add<HSimulate>(stmt->ThenId());
4526a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Visit(stmt->then_statement());
4527a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else if (stmt->condition()->ToBooleanIsFalse()) {
4528c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    Add<HSimulate>(stmt->ElseId());
4529a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Visit(stmt->else_statement());
4530a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
45318f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    HBasicBlock* cond_true = graph()->CreateBasicBlock();
45328f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    HBasicBlock* cond_false = graph()->CreateBasicBlock();
4533160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    CHECK_BAILOUT(VisitForControl(stmt->condition(), cond_true, cond_false));
45345f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4535160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    if (cond_true->HasPredecessor()) {
4536160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      cond_true->SetJoinId(stmt->ThenId());
4537160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      set_current_block(cond_true);
4538160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      CHECK_BAILOUT(Visit(stmt->then_statement()));
4539160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      cond_true = current_block();
4540160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    } else {
4541160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      cond_true = NULL;
4542160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    }
45435f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4544160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    if (cond_false->HasPredecessor()) {
4545160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      cond_false->SetJoinId(stmt->ElseId());
4546160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      set_current_block(cond_false);
4547160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      CHECK_BAILOUT(Visit(stmt->else_statement()));
4548160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      cond_false = current_block();
4549160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    } else {
4550160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      cond_false = NULL;
4551160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    }
45525f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
4553d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org    HBasicBlock* join = CreateJoin(cond_true, cond_false, stmt->IfId());
45548f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    set_current_block(join);
45553a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
45563a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}
45573a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
45583a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
4559a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHBasicBlock* HOptimizedGraphBuilder::BreakAndContinueScope::Get(
45603a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    BreakableStatement* stmt,
4561be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org    BreakType type,
45621e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    Scope** scope,
4563be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org    int* drop_extra) {
4564be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  *drop_extra = 0;
45653a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  BreakAndContinueScope* current = this;
45663a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  while (current != NULL && current->info()->target() != stmt) {
4567be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org    *drop_extra += current->info()->drop_extra();
45683a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    current = current->next();
45693a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
45703a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(current != NULL);  // Always found (unless stack is malformed).
45711e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  *scope = current->info()->scope();
4572be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
4573be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  if (type == BREAK) {
4574be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org    *drop_extra += current->info()->drop_extra();
4575be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  }
4576be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
45773a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  HBasicBlock* block = NULL;
45783a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  switch (type) {
45793a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    case BREAK:
45803a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      block = current->info()->break_block();
45813a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      if (block == NULL) {
45823a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org        block = current->owner()->graph()->CreateBasicBlock();
45833a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org        current->info()->set_break_block(block);
45843a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      }
45853a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      break;
45863a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
45873a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    case CONTINUE:
45883a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      block = current->info()->continue_block();
45893a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      if (block == NULL) {
45903a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org        block = current->owner()->graph()->CreateBasicBlock();
45913a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org        current->info()->set_continue_block(block);
45923a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      }
45933a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      break;
4594a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
45953a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
45963a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  return block;
4597a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4598a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4599a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4600a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitContinueStatement(
4601a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    ContinueStatement* stmt) {
4602160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
4603160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
4604160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
46051e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  Scope* outer_scope = NULL;
46061e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  Scope* inner_scope = scope();
4607be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  int drop_extra = 0;
4608c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  HBasicBlock* continue_block = break_scope()->Get(
46091e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      stmt->target(), BreakAndContinueScope::CONTINUE,
46101e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      &outer_scope, &drop_extra);
46111e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  HValue* context = environment()->context();
4612be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  Drop(drop_extra);
46131e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  int context_pop_count = inner_scope->ContextChainLength(outer_scope);
46141e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  if (context_pop_count > 0) {
46151e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    while (context_pop_count-- > 0) {
46161e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      HInstruction* context_instruction = Add<HLoadNamedField>(
46171e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org          context, static_cast<HValue*>(NULL),
46181e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org          HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX));
46191e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      context = context_instruction;
46201e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    }
46211e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    HInstruction* instr = Add<HStoreFrameContext>(context);
46221e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    if (instr->HasObservableSideEffects()) {
46231e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      AddSimulate(stmt->target()->EntryId(), REMOVABLE_SIMULATE);
46241e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    }
46251e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    environment()->BindContext(context);
46261e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  }
46271e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org
462871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  Goto(continue_block);
46293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  set_current_block(NULL);
4630a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4631a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4632a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4633a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitBreakStatement(BreakStatement* stmt) {
4634160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
4635160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
4636160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
46371e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  Scope* outer_scope = NULL;
46381e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  Scope* inner_scope = scope();
4639be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  int drop_extra = 0;
4640c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  HBasicBlock* break_block = break_scope()->Get(
46411e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      stmt->target(), BreakAndContinueScope::BREAK,
46421e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      &outer_scope, &drop_extra);
46431e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  HValue* context = environment()->context();
4644be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  Drop(drop_extra);
46451e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  int context_pop_count = inner_scope->ContextChainLength(outer_scope);
46461e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  if (context_pop_count > 0) {
46471e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    while (context_pop_count-- > 0) {
46481e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      HInstruction* context_instruction = Add<HLoadNamedField>(
46491e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org          context, static_cast<HValue*>(NULL),
46501e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org          HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX));
46511e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      context = context_instruction;
46521e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    }
46531e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    HInstruction* instr = Add<HStoreFrameContext>(context);
46541e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    if (instr->HasObservableSideEffects()) {
46551e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      AddSimulate(stmt->target()->ExitId(), REMOVABLE_SIMULATE);
46561e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    }
46571e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    environment()->BindContext(context);
46581e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  }
465971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  Goto(break_block);
46603a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  set_current_block(NULL);
4661a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4662a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4663a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4664a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
4665160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
4666160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
4667160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
4668471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  FunctionState* state = function_state();
4669a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  AstContext* context = call_context();
4670a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (context == NULL) {
4671a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Not an inlined return, so an actual one.
4672160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    CHECK_ALIVE(VisitForValue(stmt->expression()));
4673a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    HValue* result = environment()->Pop();
4674c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    Add<HReturn>(result);
4675471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  } else if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) {
4676471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    // Return from an inlined construct call. In a test context the return value
4677471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    // will always evaluate to true, in a value context the return value needs
4678471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    // to be a JSObject.
4679967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    if (context->IsTest()) {
4680967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      TestContext* test = TestContext::cast(context);
4681967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      CHECK_ALIVE(VisitForEffect(stmt->expression()));
468271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org      Goto(test->if_true(), state);
4683967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    } else if (context->IsEffect()) {
4684967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      CHECK_ALIVE(VisitForEffect(stmt->expression()));
468571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org      Goto(function_return(), state);
4686967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    } else {
4687967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      ASSERT(context->IsValue());
4688967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      CHECK_ALIVE(VisitForValue(stmt->expression()));
4689967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      HValue* return_value = Pop();
4690471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      HValue* receiver = environment()->arguments_environment()->Lookup(0);
4691967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      HHasInstanceTypeAndBranch* typecheck =
4692dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org          New<HHasInstanceTypeAndBranch>(return_value,
4693dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org                                         FIRST_SPEC_OBJECT_TYPE,
4694dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org                                         LAST_SPEC_OBJECT_TYPE);
4695967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      HBasicBlock* if_spec_object = graph()->CreateBasicBlock();
4696967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      HBasicBlock* not_spec_object = graph()->CreateBasicBlock();
4697967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      typecheck->SetSuccessorAt(0, if_spec_object);
4698967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      typecheck->SetSuccessorAt(1, not_spec_object);
469971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org      FinishCurrentBlock(typecheck);
470071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org      AddLeaveInlined(if_spec_object, return_value, state);
470171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org      AddLeaveInlined(not_spec_object, receiver, state);
4702471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    }
4703471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  } else if (state->inlining_kind() == SETTER_CALL_RETURN) {
4704471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    // Return from an inlined setter call. The returned value is never used, the
4705471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    // value of an assignment is always the value of the RHS of the assignment.
4706471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    CHECK_ALIVE(VisitForEffect(stmt->expression()));
4707471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    if (context->IsTest()) {
4708471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      HValue* rhs = environment()->arguments_environment()->Lookup(1);
4709471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      context->ReturnValue(rhs);
4710471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    } else if (context->IsEffect()) {
471171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org      Goto(function_return(), state);
4712471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    } else {
4713471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      ASSERT(context->IsValue());
4714471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      HValue* rhs = environment()->arguments_environment()->Lookup(1);
471571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org      AddLeaveInlined(rhs, state);
4716967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    }
4717a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
4718471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    // Return from a normal inlined function. Visit the subexpression in the
4719a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // expression context of the call.
4720a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (context->IsTest()) {
4721a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      TestContext* test = TestContext::cast(context);
4722471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      VisitForControl(stmt->expression(), test->if_true(), test->if_false());
47234d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    } else if (context->IsEffect()) {
4724fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      // Visit in value context and ignore the result. This is needed to keep
4725fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      // environment in sync with full-codegen since some visitors (e.g.
4726fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      // VisitCountOperation) use the operand stack differently depending on
4727fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      // context.
4728fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      CHECK_ALIVE(VisitForValue(stmt->expression()));
4729fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      Pop();
473071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org      Goto(function_return(), state);
4731a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    } else {
47324d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org      ASSERT(context->IsValue());
4733160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      CHECK_ALIVE(VisitForValue(stmt->expression()));
473471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org      AddLeaveInlined(Pop(), state);
4735a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
4736a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
4737967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  set_current_block(NULL);
4738a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4739a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4740a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4741a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitWithStatement(WithStatement* stmt) {
4742160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
4743160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
4744160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
4745594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return Bailout(kWithStatement);
4746a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4747a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4748a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4749a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
4750160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
4751160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
4752160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
4753c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
47544f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  // We only optimize switch statements with a bounded number of clauses.
47554d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  const int kCaseClauseLimit = 128;
4756a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ZoneList<CaseClause*>* clauses = stmt->cases();
47574d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  int clause_count = clauses->length();
47584f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  ZoneList<HBasicBlock*> body_blocks(clause_count, zone());
47594d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  if (clause_count > kCaseClauseLimit) {
4760594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return Bailout(kSwitchStatementTooManyClauses);
47614d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  }
47624d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org
4763160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  CHECK_ALIVE(VisitForValue(stmt->tag()));
4764c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  Add<HSimulate>(stmt->EntryId());
47654f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  HValue* tag_value = Top();
47666d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  Type* tag_type = stmt->tag()->bounds().lower;
47670ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
4768c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  // 1. Build all the tests, with dangling true branches
4769471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  BailoutId default_id = BailoutId::None();
47700ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  for (int i = 0; i < clause_count; ++i) {
47710ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    CaseClause* clause = clauses->at(i);
477264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    if (clause->is_default()) {
47734f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      body_blocks.Add(NULL, zone());
47744f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      if (default_id.IsNone()) default_id = clause->EntryId();
477564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      continue;
477664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    }
4777a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
47780ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    // Generate a compare and branch.
4779160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    CHECK_ALIVE(VisitForValue(clause->label()));
47804d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    HValue* label_value = Pop();
47810ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
47826d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org    Type* label_type = clause->label()->bounds().lower;
47836d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org    Type* combined_type = clause->compare_type();
47844f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org    HControlInstruction* compare = BuildCompareInstruction(
47854f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org        Token::EQ_STRICT, tag_value, label_value, tag_type, label_type,
4786f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        combined_type,
4787f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        ScriptPositionToSourcePosition(stmt->tag()->position()),
4788f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        ScriptPositionToSourcePosition(clause->label()->position()),
4789f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        PUSH_BEFORE_SIMULATE, clause->id());
47904f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org
47914d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    HBasicBlock* next_test_block = graph()->CreateBasicBlock();
47920ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry    HBasicBlock* body_block = graph()->CreateBasicBlock();
47934f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org    body_blocks.Add(body_block, zone());
47944f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    compare->SetSuccessorAt(0, body_block);
47954f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    compare->SetSuccessorAt(1, next_test_block);
479671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    FinishCurrentBlock(compare);
47970ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
47984f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org    set_current_block(body_block);
47994f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org    Drop(1);  // tag_value
48004f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org
48014d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    set_current_block(next_test_block);
48024d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  }
48034d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org
48044d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  // Save the current block to use for the default or to join with the
4805d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  // exit.
48064d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  HBasicBlock* last_block = current_block();
48074f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  Drop(1);  // tag_value
48080ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
4809c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  // 2. Loop over the clauses and the linked list of tests in lockstep,
48104d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  // translating the clause bodies.
48114d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  HBasicBlock* fall_through_block = NULL;
48120ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
48131e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  BreakAndContinueInfo break_info(stmt, scope());
48144d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  { BreakAndContinueScope push(&break_info, this);
48154d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    for (int i = 0; i < clause_count; ++i) {
48164d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org      CaseClause* clause = clauses->at(i);
48174d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org
48184d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org      // Identify the block where normal (non-fall-through) control flow
48194d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org      // goes to.
48204d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org      HBasicBlock* normal_block = NULL;
482113da64d34f16ec991f0926be7747eb17ad34a05dfschneider@chromium.org      if (clause->is_default()) {
48224f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org        if (last_block == NULL) continue;
48234f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org        normal_block = last_block;
48244f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org        last_block = NULL;  // Cleared to indicate we've handled it.
4825c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org      } else {
48264f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org        normal_block = body_blocks[i];
48274d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org      }
48285f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
48294f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      if (fall_through_block == NULL) {
48304d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org        set_current_block(normal_block);
48315f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org      } else {
48324d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org        HBasicBlock* join = CreateJoin(fall_through_block,
48334d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org                                       normal_block,
48344d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org                                       clause->EntryId());
48354d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org        set_current_block(join);
48365f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org      }
4837a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4838160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      CHECK_BAILOUT(VisitStatements(clause->statements()));
48394d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org      fall_through_block = current_block();
4840a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
4841a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
4842a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
48434d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  // Create an up-to-3-way join.  Use the break block if it exists since
48444d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  // it's already a join block.
48454d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  HBasicBlock* break_block = break_info.break_block();
48464d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  if (break_block == NULL) {
48474d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    set_current_block(CreateJoin(fall_through_block,
48484d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org                                 last_block,
48494d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org                                 stmt->ExitId()));
4850a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
485171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    if (fall_through_block != NULL) Goto(fall_through_block, break_block);
485271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    if (last_block != NULL) Goto(last_block, break_block);
48534d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    break_block->SetJoinId(stmt->ExitId());
48544d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    set_current_block(break_block);
4855a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
4856a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4857a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
48584d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org
4859a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt,
48601e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org                                           HBasicBlock* loop_entry) {
4861c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  Add<HSimulate>(stmt->StackCheckId());
48628e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  HStackCheck* stack_check =
48638e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org      HStackCheck::cast(Add<HStackCheck>(HStackCheck::kBackwardsBranch));
486404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  ASSERT(loop_entry->IsLoopHeader());
486504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  loop_entry->loop_information()->set_stack_check(stack_check);
4866ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  CHECK_BAILOUT(Visit(stmt->body()));
486704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org}
486804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org
486904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org
4870a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
4871160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
4872160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
4873160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
48743a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(current_block() != NULL);
4875c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  HBasicBlock* loop_entry = BuildLoopEntry(stmt);
4876a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
48771e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  BreakAndContinueInfo break_info(stmt, scope());
48781e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  {
48791e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    BreakAndContinueScope push(&break_info, this);
48801e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry));
48811e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  }
48829ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  HBasicBlock* body_exit =
48839ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org      JoinContinue(stmt, current_block(), break_info.continue_block());
48848f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  HBasicBlock* loop_successor = NULL;
48858f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  if (body_exit != NULL && !stmt->cond()->ToBooleanIsTrue()) {
48869ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    set_current_block(body_exit);
48878f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    loop_successor = graph()->CreateBasicBlock();
4888034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org    if (stmt->cond()->ToBooleanIsFalse()) {
4889285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org      loop_entry->loop_information()->stack_check()->Eliminate();
4890034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org      Goto(loop_successor);
4891034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org      body_exit = NULL;
4892034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org    } else {
4893034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org      // The block for a true condition, the actual predecessor block of the
4894034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org      // back edge.
4895034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org      body_exit = graph()->CreateBasicBlock();
4896034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org      CHECK_BAILOUT(VisitForControl(stmt->cond(), body_exit, loop_successor));
4897034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org    }
4898034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org    if (body_exit != NULL && body_exit->HasPredecessor()) {
4899160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      body_exit->SetJoinId(stmt->BackEdgeId());
4900160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    } else {
4901160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      body_exit = NULL;
4902160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    }
4903160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    if (loop_successor->HasPredecessor()) {
4904160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      loop_successor->SetJoinId(stmt->ExitId());
4905160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    } else {
4906160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      loop_successor = NULL;
4907160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    }
49088f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  }
49098f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  HBasicBlock* loop_exit = CreateLoop(stmt,
49108f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                                      loop_entry,
49118f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                                      body_exit,
49128f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                                      loop_successor,
49138f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                                      break_info.break_block());
49149ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  set_current_block(loop_exit);
4915a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4916a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4917a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4918a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
4919160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
4920160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
4921160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
49223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(current_block() != NULL);
4923c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  HBasicBlock* loop_entry = BuildLoopEntry(stmt);
4924a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
49259ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  // If the condition is constant true, do not generate a branch.
49268f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  HBasicBlock* loop_successor = NULL;
49279ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  if (!stmt->cond()->ToBooleanIsTrue()) {
49288f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    HBasicBlock* body_entry = graph()->CreateBasicBlock();
49298f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    loop_successor = graph()->CreateBasicBlock();
4930160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor));
4931160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    if (body_entry->HasPredecessor()) {
4932160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      body_entry->SetJoinId(stmt->BodyId());
4933160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      set_current_block(body_entry);
4934160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    }
4935160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    if (loop_successor->HasPredecessor()) {
4936160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      loop_successor->SetJoinId(stmt->ExitId());
4937160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    } else {
4938160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      loop_successor = NULL;
4939160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    }
4940a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
4941a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
49421e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  BreakAndContinueInfo break_info(stmt, scope());
4943160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  if (current_block() != NULL) {
49441e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    BreakAndContinueScope push(&break_info, this);
49451e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry));
4946a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
49479ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  HBasicBlock* body_exit =
49489ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org      JoinContinue(stmt, current_block(), break_info.continue_block());
49498f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  HBasicBlock* loop_exit = CreateLoop(stmt,
49508f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                                      loop_entry,
49518f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                                      body_exit,
49528f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                                      loop_successor,
49538f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                                      break_info.break_block());
49549ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  set_current_block(loop_exit);
4955a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
4956a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4957a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4958a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitForStatement(ForStatement* stmt) {
4959160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
4960160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
4961160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
49628f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  if (stmt->init() != NULL) {
4963160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    CHECK_ALIVE(Visit(stmt->init()));
4964a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
49653a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(current_block() != NULL);
4966c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  HBasicBlock* loop_entry = BuildLoopEntry(stmt);
4967a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
49688f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  HBasicBlock* loop_successor = NULL;
4969a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (stmt->cond() != NULL) {
49708f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    HBasicBlock* body_entry = graph()->CreateBasicBlock();
49718f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    loop_successor = graph()->CreateBasicBlock();
4972160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor));
4973160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    if (body_entry->HasPredecessor()) {
4974160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      body_entry->SetJoinId(stmt->BodyId());
4975160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      set_current_block(body_entry);
4976160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    }
4977160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    if (loop_successor->HasPredecessor()) {
4978160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      loop_successor->SetJoinId(stmt->ExitId());
4979160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    } else {
4980160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      loop_successor = NULL;
4981160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    }
4982a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
49839ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
49841e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  BreakAndContinueInfo break_info(stmt, scope());
4985160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  if (current_block() != NULL) {
49861e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    BreakAndContinueScope push(&break_info, this);
49871e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry));
49889ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  }
49899ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  HBasicBlock* body_exit =
49909ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org      JoinContinue(stmt, current_block(), break_info.continue_block());
49919ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
49929ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  if (stmt->next() != NULL && body_exit != NULL) {
49939ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    set_current_block(body_exit);
4994160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    CHECK_BAILOUT(Visit(stmt->next()));
49959ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    body_exit = current_block();
49969ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  }
49979ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
49988f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  HBasicBlock* loop_exit = CreateLoop(stmt,
49998f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                                      loop_entry,
50008f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                                      body_exit,
50018f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                                      loop_successor,
50028f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                                      break_info.break_block());
50039ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  set_current_block(loop_exit);
5004a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5005a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5006a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5007a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
5008160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
5009160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
5010160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
5011be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5012a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org  if (!FLAG_optimize_for_in) {
5013594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return Bailout(kForInStatementOptimizationIsDisabled);
5014a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org  }
5015a7d3df915ae6a29cd392dba32a26049d7b9b008fyangguo@chromium.org
5016c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  if (stmt->for_in_type() != ForInStatement::FAST_FOR_IN) {
5017594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return Bailout(kForInStatementIsNotFastCase);
50189a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org  }
50199a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org
5020be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  if (!stmt->each()->IsVariableProxy() ||
5021be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org      !stmt->each()->AsVariableProxy()->var()->IsStackLocal()) {
5022594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return Bailout(kForInStatementWithNonLocalEachVariable);
5023be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  }
5024be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5025be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  Variable* each_var = stmt->each()->AsVariableProxy()->var();
5026be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5027be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  CHECK_ALIVE(VisitForValue(stmt->enumerable()));
5028be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  HValue* enumerable = Top();  // Leave enumerable at the top.
5029be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5030d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* map = Add<HForInPrepareMap>(enumerable);
5031c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  Add<HSimulate>(stmt->PrepareId());
5032be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
50331510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HInstruction* array = Add<HForInCacheArray>(
50341510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      enumerable, map, DescriptorArray::kEnumCacheBridgeCacheIndex);
5035be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
50361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HInstruction* enum_length = Add<HMapEnumLength>(map);
5037be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
50381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HInstruction* start_index = Add<HConstant>(0);
5039be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5040be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  Push(map);
5041be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  Push(array);
5042355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  Push(enum_length);
5043be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  Push(start_index);
5044be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
50451510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HInstruction* index_cache = Add<HForInCacheArray>(
50461510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      enumerable, map, DescriptorArray::kEnumCacheBridgeIndicesCacheIndex);
5047be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  HForInCacheArray::cast(array)->set_index_cache(
5048be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org      HForInCacheArray::cast(index_cache));
5049be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5050c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  HBasicBlock* loop_entry = BuildLoopEntry(stmt);
5051be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5052be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  HValue* index = environment()->ExpressionStackAt(0);
5053be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  HValue* limit = environment()->ExpressionStackAt(1);
5054be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5055be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  // Check that we still have more keys.
5056e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  HCompareNumericAndBranch* compare_index =
5057528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      New<HCompareNumericAndBranch>(index, limit, Token::LT);
5058fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  compare_index->set_observed_input_representation(
5059b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      Representation::Smi(), Representation::Smi());
5060be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5061be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  HBasicBlock* loop_body = graph()->CreateBasicBlock();
5062be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  HBasicBlock* loop_successor = graph()->CreateBasicBlock();
5063be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5064be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  compare_index->SetSuccessorAt(0, loop_body);
5065be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  compare_index->SetSuccessorAt(1, loop_successor);
506671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  FinishCurrentBlock(compare_index);
5067be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5068be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  set_current_block(loop_successor);
5069be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  Drop(5);
5070be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5071be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  set_current_block(loop_body);
5072be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
50731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HValue* key = Add<HLoadKeyed>(
50741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      environment()->ExpressionStackAt(2),  // Enum cache.
50751510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      environment()->ExpressionStackAt(0),  // Iteration index.
50761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      environment()->ExpressionStackAt(0),
50771510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      FAST_ELEMENTS);
5078be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5079be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  // Check if the expected map still matches that of the enumerable.
5080be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  // If not just deoptimize.
50811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Add<HCheckMapValue>(environment()->ExpressionStackAt(4),
50821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                      environment()->ExpressionStackAt(3));
5083be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5084be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  Bind(each_var, key);
5085be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
50861e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  BreakAndContinueInfo break_info(stmt, scope(), 5);
50871e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  {
50881e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    BreakAndContinueScope push(&break_info, this);
50891e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry));
50901e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  }
5091be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5092be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  HBasicBlock* body_exit =
5093be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org      JoinContinue(stmt, current_block(), break_info.continue_block());
5094be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5095be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  if (body_exit != NULL) {
5096be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org    set_current_block(body_exit);
5097be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5098be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org    HValue* current_index = Pop();
50997ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org    Push(AddUncasted<HAdd>(current_index, graph()->GetConstant1()));
5100be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org    body_exit = current_block();
5101be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  }
5102be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5103be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  HBasicBlock* loop_exit = CreateLoop(stmt,
5104be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org                                      loop_entry,
5105be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org                                      body_exit,
5106be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org                                      loop_successor,
5107be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org                                      break_info.break_block());
5108be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
5109be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  set_current_block(loop_exit);
5110a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5111a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5112a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
51131fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.orgvoid HOptimizedGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) {
51141fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  ASSERT(!HasStackOverflow());
51151fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  ASSERT(current_block() != NULL);
51161fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  ASSERT(current_block()->HasPredecessor());
5117594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return Bailout(kForOfStatement);
51181fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org}
51191fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
51201fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
5121a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
5122160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
5123160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
5124160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
5125594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return Bailout(kTryCatchStatement);
5126a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5127a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5128a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5129a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitTryFinallyStatement(
5130a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    TryFinallyStatement* stmt) {
5131160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
5132160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
5133160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
5134594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return Bailout(kTryFinallyStatement);
5135a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5136a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5137a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5138a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) {
5139160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
5140160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
5141160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
5142594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return Bailout(kDebuggerStatement);
5143a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5144a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5145a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5146a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.orgvoid HOptimizedGraphBuilder::VisitCaseClause(CaseClause* clause) {
5147a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  UNREACHABLE();
5148a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org}
5149a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
5150a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
5151a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
5152160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
5153160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
5154160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
51554610c28af9f4355485f8115a725f320b80632804machenbach@chromium.org  Handle<SharedFunctionInfo> shared_info = expr->shared_info();
5156c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  if (shared_info.is_null()) {
515741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    shared_info = Compiler::BuildFunctionInfo(expr, current_info()->script());
5158c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  }
5159160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  // We also have a stack overflow if the recursive compilation did.
5160160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  if (HasStackOverflow()) return;
51615f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  HFunctionLiteral* instr =
51628e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org      New<HFunctionLiteral>(shared_info, expr->pretenure());
51634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnInstruction(instr, expr->id());
5164a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5165a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5166a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5167fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.orgvoid HOptimizedGraphBuilder::VisitNativeFunctionLiteral(
5168fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    NativeFunctionLiteral* expr) {
5169160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
5170160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
5171160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
5172fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  return Bailout(kNativeFunctionLiteral);
5173a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5174a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5175a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5176a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitConditional(Conditional* expr) {
5177160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
5178160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
5179160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
51808f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  HBasicBlock* cond_true = graph()->CreateBasicBlock();
51818f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  HBasicBlock* cond_false = graph()->CreateBasicBlock();
5182160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  CHECK_BAILOUT(VisitForControl(expr->condition(), cond_true, cond_false));
51838f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
51844d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  // Visit the true and false subexpressions in the same AST context as the
51854d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  // whole expression.
5186160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  if (cond_true->HasPredecessor()) {
5187160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    cond_true->SetJoinId(expr->ThenId());
5188160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    set_current_block(cond_true);
5189160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    CHECK_BAILOUT(Visit(expr->then_expression()));
5190160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    cond_true = current_block();
5191160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  } else {
5192160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    cond_true = NULL;
5193160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  }
51948f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
5195160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  if (cond_false->HasPredecessor()) {
5196160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    cond_false->SetJoinId(expr->ElseId());
5197160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    set_current_block(cond_false);
5198160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    CHECK_BAILOUT(Visit(expr->else_expression()));
5199160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    cond_false = current_block();
5200160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  } else {
5201160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    cond_false = NULL;
5202160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  }
52038f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
52044d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  if (!ast_context()->IsTest()) {
5205160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    HBasicBlock* join = CreateJoin(cond_true, cond_false, expr->id());
52064d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    set_current_block(join);
5207160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    if (join != NULL && !ast_context()->IsEffect()) {
52084f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      return ast_context()->ReturnValue(Pop());
5209160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    }
52104d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  }
5211a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5212a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5213a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5214a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHOptimizedGraphBuilder::GlobalPropertyAccess
5215a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    HOptimizedGraphBuilder::LookupGlobalProperty(
5216f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        Variable* var, LookupResult* lookup, PropertyAccessType access_type) {
521741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  if (var->is_this() || !current_info()->has_global_object()) {
5218c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    return kUseGeneric;
5219a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
522041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  Handle<GlobalObject> global(current_info()->global_object());
52213484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  global->Lookup(var->name(), lookup);
5222de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  if (!lookup->IsNormal() ||
5223f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      (access_type == STORE && lookup->IsReadOnly()) ||
5224c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      lookup->holder() != *global) {
5225c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    return kUseGeneric;
5226d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  }
5227c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
5228c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  return kUseCell;
5229a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5230a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5231a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5232a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) {
523383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  ASSERT(var->IsContextSlot());
5234d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HValue* context = environment()->context();
52351e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  int length = scope()->ContextChainLength(var->scope());
523683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  while (length-- > 0) {
5237f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    context = Add<HLoadNamedField>(
5238f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        context, static_cast<HValue*>(NULL),
5239f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX));
524083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  }
524183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  return context;
524283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org}
524383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
524483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
5245a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
5246e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  if (expr->is_this()) {
5247e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org    current_info()->set_this_has_uses(true);
5248e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  }
5249e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org
5250160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
5251160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
5252160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
5253486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  Variable* variable = expr->var();
5254486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  switch (variable->location()) {
5255486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    case Variable::UNALLOCATED: {
5256355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      if (IsLexicalVariableMode(variable->mode())) {
5257355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        // TODO(rossberg): should this be an ASSERT?
5258594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        return Bailout(kReferenceToGlobalLexicalVariable);
525964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      }
5260c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Handle known global constants like 'undefined' specially to avoid a
5261c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // load from a global cell for them.
5262c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Handle<Object> constant_value =
5263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          isolate()->factory()->GlobalConstantFor(variable->name());
5264c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (!constant_value.is_null()) {
5265d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        HConstant* instr = New<HConstant>(constant_value);
5266c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        return ast_context()->ReturnInstruction(instr, expr->id());
5267c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
5268c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5269394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      LookupResult lookup(isolate());
5270f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      GlobalPropertyAccess type = LookupGlobalProperty(variable, &lookup, LOAD);
5271486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
5272486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      if (type == kUseCell &&
527341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org          current_info()->global_object()->IsAccessCheckNeeded()) {
5274486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        type = kUseGeneric;
5275486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      }
5276badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
5277486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      if (type == kUseCell) {
527841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org        Handle<GlobalObject> global(current_info()->global_object());
5279b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        Handle<PropertyCell> cell(global->GetPropertyCell(&lookup));
5280e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org        if (cell->type()->IsConstant()) {
5281e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org          PropertyCell::AddDependentCompilationInfo(cell, top_info());
52829fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org          Handle<Object> constant_object = cell->type()->AsConstant()->Value();
5283e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org          if (constant_object->IsConsString()) {
5284e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org            constant_object =
52859e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                String::Flatten(Handle<String>::cast(constant_object));
5286e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org          }
5287d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          HConstant* constant = New<HConstant>(constant_object);
5288e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org          return ast_context()->ReturnInstruction(constant, expr->id());
5289e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org        } else {
5290e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org          HLoadGlobalCell* instr =
5291db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org              New<HLoadGlobalCell>(cell, lookup.GetPropertyDetails());
5292e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org          return ast_context()->ReturnInstruction(instr, expr->id());
5293e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org        }
5294486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      } else {
529505150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org        HValue* global_object = Add<HLoadNamedField>(
529609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org            context(), static_cast<HValue*>(NULL),
529709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org            HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
5298486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        HLoadGlobalGeneric* instr =
5299db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org            New<HLoadGlobalGeneric>(global_object,
5300db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org                                    variable->name(),
5301db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org                                    ast_context()->is_for_typeof());
5302486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        return ast_context()->ReturnInstruction(instr, expr->id());
5303486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      }
5304c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    }
5305c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
5306486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    case Variable::PARAMETER:
5307486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    case Variable::LOCAL: {
5308d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      HValue* value = LookupAndMakeLive(variable);
530964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      if (value == graph()->GetConstantHole()) {
5310355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        ASSERT(IsDeclaredVariableMode(variable->mode()) &&
5311355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org               variable->mode() != VAR);
5312594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        return Bailout(kReferenceToUninitializedVariable);
5313486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      }
5314486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      return ast_context()->ReturnValue(value);
5315486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    }
5316486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
5317486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    case Variable::CONTEXT: {
5318486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      HValue* context = BuildContextChainWalk(variable);
53191e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      HLoadContextSlot::Mode mode;
53201e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      switch (variable->mode()) {
53211e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org        case LET:
53221e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org        case CONST:
53231e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org          mode = HLoadContextSlot::kCheckDeoptimize;
53241e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org          break;
53251e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org        case CONST_LEGACY:
53261e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org          mode = HLoadContextSlot::kCheckReturnUndefined;
53271e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org          break;
53281e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org        default:
53291e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org          mode = HLoadContextSlot::kNoCheck;
53301e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org          break;
53311e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      }
53321e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org      HLoadContextSlot* instr =
53331e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org          new(zone()) HLoadContextSlot(context, variable->index(), mode);
53344f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      return ast_context()->ReturnInstruction(instr, expr->id());
53355f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    }
5336486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
5337486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    case Variable::LOOKUP:
5338594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      return Bailout(kReferenceToAVariableWhichRequiresDynamicLookup);
5339a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
5340a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5341a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5342a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5343a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitLiteral(Literal* expr) {
5344160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
5345160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
5346160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
5347d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HConstant* instr = New<HConstant>(expr->value());
53484f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnInstruction(instr, expr->id());
5349a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5350a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5351a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5352a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
5353160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
5354160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
5355160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
53569c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org  Handle<JSFunction> closure = function_state()->compilation_info()->closure();
53579c741c80bfc8026103e86b46e15e2544095ce67eyangguo@chromium.org  Handle<FixedArray> literals(closure->literals());
53588e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  HRegExpLiteral* instr = New<HRegExpLiteral>(literals,
53598e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org                                              expr->pattern(),
53608e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org                                              expr->flags(),
53618e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org                                              expr->literal_index());
53624f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnInstruction(instr, expr->id());
5363a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5364a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5365a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
53660a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.orgstatic bool CanInlinePropertyAccess(Type* type) {
53670a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  if (type->Is(Type::NumberOrString())) return true;
536857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  if (!type->IsClass()) return false;
53699fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<Map> map = type->AsClass()->Map();
537057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  return map->IsJSObjectMap() &&
537157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      !map->is_dictionary_map() &&
537257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      !map->has_named_interceptor();
5373e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org}
5374e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org
5375e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org
5376f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org// Determines whether the given array or object literal boilerplate satisfies
5377f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org// all limits to be considered for fast deep-copying and computes the total
53781b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org// size of all objects that are part of the graph.
5379f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgstatic bool IsFastLiteral(Handle<JSObject> boilerplate,
5380f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org                          int max_depth,
5381dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org                          int* max_properties) {
5382a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org  if (boilerplate->map()->is_deprecated() &&
5383a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org      !JSObject::TryMigrateInstance(boilerplate)) {
5384a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org    return false;
5385a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  }
5386a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5387f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  ASSERT(max_depth >= 0 && *max_properties >= 0);
5388f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  if (max_depth == 0) return false;
53891b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
539009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Isolate* isolate = boilerplate->GetIsolate();
539164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  Handle<FixedArrayBase> elements(boilerplate->elements());
53921b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  if (elements->length() > 0 &&
539309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org      elements->map() != isolate->heap()->fixed_cow_array_map()) {
5394dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    if (boilerplate->HasFastObjectElements()) {
5395ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements);
539688aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org      int length = elements->length();
539788aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org      for (int i = 0; i < length; i++) {
539888aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org        if ((*max_properties)-- == 0) return false;
539909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org        Handle<Object> value(fast_elements->get(i), isolate);
540088aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org        if (value->IsJSObject()) {
540188aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org          Handle<JSObject> value_object = Handle<JSObject>::cast(value);
540288aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org          if (!IsFastLiteral(value_object,
540388aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org                             max_depth - 1,
5404dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org                             max_properties)) {
540588aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org            return false;
540688aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org          }
5407f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org        }
5408f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      }
5409dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    } else if (!boilerplate->HasFastDoubleElements()) {
541088aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org      return false;
5411f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    }
54121b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
54131b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
541464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  Handle<FixedArray> properties(boilerplate->properties());
54151b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  if (properties->length() > 0) {
54161b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    return false;
54171b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  } else {
541857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    Handle<DescriptorArray> descriptors(
541957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org        boilerplate->map()->instance_descriptors());
542057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    int limit = boilerplate->map()->NumberOfOwnDescriptors();
542157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    for (int i = 0; i < limit; i++) {
542257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      PropertyDetails details = descriptors->GetDetails(i);
542357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      if (details.type() != FIELD) continue;
542457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      int index = descriptors->GetFieldIndex(i);
5425f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org      if ((*max_properties)-- == 0) return false;
542657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      Handle<Object> value(boilerplate->InObjectPropertyAt(index), isolate);
54271b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      if (value->IsJSObject()) {
54281b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        Handle<JSObject> value_object = Handle<JSObject>::cast(value);
5429f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org        if (!IsFastLiteral(value_object,
5430f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org                           max_depth - 1,
5431dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org                           max_properties)) {
54321b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          return false;
54331b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        }
54341b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      }
54351b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    }
54361b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
54371b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  return true;
54381b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org}
54391b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
54401b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
5441a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
5442160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
5443160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
5444160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
5445e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  expr->BuildConstantProperties(isolate());
54461b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  Handle<JSFunction> closure = function_state()->compilation_info()->closure();
54471b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  HInstruction* literal;
54481b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
54491b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  // Check whether to use fast or slow deep-copying for boilerplate.
5450e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  int max_properties = kMaxFastLiteralProperties;
5451dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  Handle<Object> literals_cell(closure->literals()->get(expr->literal_index()),
5452dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org                               isolate());
5453dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  Handle<AllocationSite> site;
5454dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  Handle<JSObject> boilerplate;
5455dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  if (!literals_cell->IsUndefined()) {
5456dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org    // Retrieve the boilerplate
5457dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org    site = Handle<AllocationSite>::cast(literals_cell);
5458dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org    boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()),
5459dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org                                   isolate());
5460dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  }
5461e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
5462dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  if (!boilerplate.is_null() &&
5463dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org      IsFastLiteral(boilerplate, kMaxFastLiteralDepth, &max_properties)) {
5464b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    AllocationSiteUsageContext usage_context(isolate(), site, false);
5465b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    usage_context.EnterNewScope();
5466b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    literal = BuildFastLiteral(boilerplate, &usage_context);
5467b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    usage_context.ExitScope(site, boilerplate);
54681b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  } else {
5469906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    NoObservableSideEffectsScope no_effects(this);
547032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    Handle<FixedArray> closure_literals(closure->literals(), isolate());
5471906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    Handle<FixedArray> constant_properties = expr->constant_properties();
5472906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    int literal_index = expr->literal_index();
5473906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    int flags = expr->fast_elements()
5474906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org        ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags;
5475906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    flags |= expr->has_function()
5476906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org        ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags;
5477906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org
54788d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    Add<HPushArguments>(Add<HConstant>(closure_literals),
5479011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org                        Add<HConstant>(literal_index),
5480011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org                        Add<HConstant>(constant_properties),
5481011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org                        Add<HConstant>(flags));
5482906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org
5483b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    // TODO(mvstanton): Add a flag to turn off creation of any
5484b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    // AllocationMementos for this call: we are in crankshaft and should have
5485b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    // learned enough about transition behavior to stop emitting mementos.
5486895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    Runtime::FunctionId function_id = Runtime::kHiddenCreateObjectLiteral;
5487d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    literal = Add<HCallRuntime>(isolate()->factory()->empty_string(),
54881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                Runtime::FunctionForId(function_id),
54891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                4);
54901b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
54911b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
54925f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // The object is expected in the bailout environment during computation
54935f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // of the property values and is the value of the entire expression.
5494e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Push(literal);
5495a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
54967028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  expr->CalculateEmitStore(zone());
5497a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5498a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < expr->properties()->length(); i++) {
5499a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ObjectLiteral::Property* property = expr->properties()->at(i);
5500a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (property->IsCompileTimeValue()) continue;
5501a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5502a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Literal* key = property->key();
5503a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Expression* value = property->value();
5504a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5505a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    switch (property->kind()) {
5506a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      case ObjectLiteral::Property::MATERIALIZED_LITERAL:
5507a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        ASSERT(!CompileTimeValue::IsCompileTimeValue(value));
5508a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        // Fall through.
5509a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      case ObjectLiteral::Property::COMPUTED:
55101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        if (key->value()->IsInternalizedString()) {
5511a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          if (property->emit_store()) {
5512160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org            CHECK_ALIVE(VisitForValue(value));
5513a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            HValue* value = Pop();
5514b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org            Handle<Map> map = property->GetReceiverType();
5515b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org            Handle<String> name = property->key()->AsPropertyName();
55167028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org            HInstruction* store;
5517b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org            if (map.is_null()) {
5518b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org              // If we don't know the monomorphic type, do a generic store.
5519f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org              CHECK_ALIVE(store = BuildNamedGeneric(
5520f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                  STORE, literal, name, value));
5521b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org            } else {
55220a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org              PropertyAccessInfo info(this, STORE, ToType(map), name);
55230a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org              if (info.CanAccessMonomorphic()) {
5524af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org                HValue* checked_literal = Add<HCheckMaps>(literal, map);
55250a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                ASSERT(!info.lookup()->IsPropertyCallbacks());
55268297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                store = BuildMonomorphicAccess(
55278297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                    &info, literal, checked_literal, value,
55280a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                    BailoutId::None(), BailoutId::None());
55290a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org              } else {
5530f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                CHECK_ALIVE(store = BuildNamedGeneric(
5531f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                    STORE, literal, name, value));
55320a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org              }
5533b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org            }
5534496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org            AddInstruction(store);
5535fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            if (store->HasObservableSideEffects()) {
5536c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org              Add<HSimulate>(key->id(), REMOVABLE_SIMULATE);
5537fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            }
5538a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          } else {
5539160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org            CHECK_ALIVE(VisitForEffect(value));
5540a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          }
5541a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          break;
5542a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        }
5543a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        // Fall through.
5544a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      case ObjectLiteral::Property::PROTOTYPE:
5545a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      case ObjectLiteral::Property::SETTER:
5546a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      case ObjectLiteral::Property::GETTER:
5547594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        return Bailout(kObjectLiteralWithComplexProperty);
5548a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      default: UNREACHABLE();
5549a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
5550a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
5551ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
5552ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (expr->has_function()) {
5553ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    // Return the result of the transformation to fast properties
5554ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    // instead of the original since this operation changes the map
5555ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    // of the object. This makes sure that the original object won't
5556ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    // be used by other optimized code before it is transformed
5557ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    // (e.g. because of code motion).
55581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    HToFastProperties* result = Add<HToFastProperties>(Pop());
55594f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    return ast_context()->ReturnValue(result);
5560ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  } else {
55614f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    return ast_context()->ReturnValue(Pop());
5562ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
5563a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5564a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5565a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5566a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
5567160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
5568160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
5569160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
5570e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  expr->BuildConstantElements(isolate());
5571a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ZoneList<Expression*>* subexprs = expr->values();
5572a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int length = subexprs->length();
5573f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  HInstruction* literal;
5574a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5575bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  Handle<AllocationSite> site;
557632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  Handle<FixedArray> literals(environment()->closure()->literals(), isolate());
5577c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  bool uninitialized = false;
5578bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  Handle<Object> literals_cell(literals->get(expr->literal_index()),
5579bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org                               isolate());
5580b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  Handle<JSObject> boilerplate_object;
5581bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  if (literals_cell->IsUndefined()) {
5582c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    uninitialized = true;
55838f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    Handle<Object> raw_boilerplate;
55848f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    ASSIGN_RETURN_ON_EXCEPTION_VALUE(
55858f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org        isolate(), raw_boilerplate,
55868f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org        Runtime::CreateArrayLiteralBoilerplate(
55878f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org            isolate(), literals, expr->constant_elements()),
55888f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org        Bailout(kArrayBoilerplateCreationFailed));
5589bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
5590b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    boilerplate_object = Handle<JSObject>::cast(raw_boilerplate);
5591b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    AllocationSiteCreationContext creation_context(isolate());
5592b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    site = creation_context.EnterNewScope();
5593b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    if (JSObject::DeepWalk(boilerplate_object, &creation_context).is_null()) {
5594b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org      return Bailout(kArrayBoilerplateCreationFailed);
5595b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    }
5596b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    creation_context.ExitScope(site, boilerplate_object);
5597bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    literals->set(expr->literal_index(), *site);
5598bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
5599b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    if (boilerplate_object->elements()->map() ==
56007ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org        isolate()->heap()->fixed_cow_array_map()) {
56017ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      isolate()->counters()->cow_arrays_created_runtime()->Increment();
56027ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    }
5603bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  } else {
5604bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    ASSERT(literals_cell->IsAllocationSite());
5605bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    site = Handle<AllocationSite>::cast(literals_cell);
5606b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    boilerplate_object = Handle<JSObject>(
5607b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org        JSObject::cast(site->transition_info()), isolate());
560864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  }
560964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
5610b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  ASSERT(!boilerplate_object.is_null());
5611b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  ASSERT(site->SitePointsToLiteral());
5612bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
56137ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org  ElementsKind boilerplate_elements_kind =
5614b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org      boilerplate_object->GetElementsKind();
561564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
5616f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // Check whether to use fast or slow deep-copying for boilerplate.
5617e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  int max_properties = kMaxFastLiteralProperties;
5618dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  if (IsFastLiteral(boilerplate_object,
5619e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                    kMaxFastLiteralDepth,
5620dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org                    &max_properties)) {
5621b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    AllocationSiteUsageContext usage_context(isolate(), site, false);
5622b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    usage_context.EnterNewScope();
5623b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    literal = BuildFastLiteral(boilerplate_object, &usage_context);
5624b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    usage_context.ExitScope(site, boilerplate_object);
5625f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  } else {
5626906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    NoObservableSideEffectsScope no_effects(this);
5627906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    // Boilerplate already exists and constant elements are never accessed,
5628906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    // pass an empty fixed array to the runtime function instead.
5629906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array();
5630906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    int literal_index = expr->literal_index();
563137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    int flags = expr->depth() == 1
563237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        ? ArrayLiteral::kShallowElements
563337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        : ArrayLiteral::kNoFlags;
563437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    flags |= ArrayLiteral::kDisableMementos;
5635906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org
56368d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    Add<HPushArguments>(Add<HConstant>(literals),
5637011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org                        Add<HConstant>(literal_index),
5638011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org                        Add<HConstant>(constants),
5639011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org                        Add<HConstant>(flags));
5640906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org
5641b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    // TODO(mvstanton): Consider a flag to turn off creation of any
5642b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    // AllocationMementos for this call: we are in crankshaft and should have
5643b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    // learned enough about transition behavior to stop emitting mementos.
5644895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    Runtime::FunctionId function_id = Runtime::kHiddenCreateArrayLiteral;
5645d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    literal = Add<HCallRuntime>(isolate()->factory()->empty_string(),
56461510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                Runtime::FunctionForId(function_id),
564737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org                                4);
5648fee992bb82f8bc64bb35d7133567a2f6d2671b64jkummerow@chromium.org
5649fee992bb82f8bc64bb35d7133567a2f6d2671b64jkummerow@chromium.org    // De-opt if elements kind changed from boilerplate_elements_kind.
5650dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    Handle<Map> map = Handle<Map>(boilerplate_object->map(), isolate());
5651af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    literal = Add<HCheckMaps>(literal, map);
5652f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  }
565364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
56545f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // The array is expected in the bailout environment during computation
56555f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // of the property values and is the value of the entire expression.
5656e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Push(literal);
5657b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  // The literal index is on the stack, too.
56581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Push(Add<HConstant>(expr->literal_index()));
56595f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
566057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  HInstruction* elements = NULL;
5661a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5662a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < length; i++) {
5663a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Expression* subexpr = subexprs->at(i);
5664a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // If the subexpression is a literal or a simple materialized literal it
5665a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // is already set in the cloned array.
5666a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
5667a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5668160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    CHECK_ALIVE(VisitForValue(subexpr));
5669a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    HValue* value = Pop();
5670594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (!Smi::IsValid(i)) return Bailout(kNonSmiKeyInArrayLiteral);
56715f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
5672ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org    elements = AddLoadElements(literal);
56735f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
56741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    HValue* key = Add<HConstant>(i);
5675a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org
567664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    switch (boilerplate_elements_kind) {
5677830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      case FAST_SMI_ELEMENTS:
5678830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      case FAST_HOLEY_SMI_ELEMENTS:
567964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      case FAST_ELEMENTS:
5680830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      case FAST_HOLEY_ELEMENTS:
5681e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      case FAST_DOUBLE_ELEMENTS:
5682c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org      case FAST_HOLEY_DOUBLE_ELEMENTS: {
5683c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org        HStoreKeyed* instr = Add<HStoreKeyed>(elements, key, value,
56840a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                                              boilerplate_elements_kind);
5685c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org        instr->SetUninitialized(uninitialized);
568664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org        break;
5687c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org      }
568864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      default:
568964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org        UNREACHABLE();
569064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org        break;
569164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    }
5692c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5693c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    Add<HSimulate>(expr->GetIdForElement(i));
5694a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
5695b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
5696b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  Drop(1);  // array literal index
56974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnValue(Pop());
5698a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5699a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5700a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5701003a9255d4e3b18b610295c0de79b1dbedc021c7verwaest@chromium.orgHCheckMaps* HOptimizedGraphBuilder::AddCheckMap(HValue* object,
5702003a9255d4e3b18b610295c0de79b1dbedc021c7verwaest@chromium.org                                                Handle<Map> map) {
57031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  BuildCheckHeapObject(object);
5704af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  return Add<HCheckMaps>(object, map);
5705e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org}
5706e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
5707e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
5708f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgHInstruction* HOptimizedGraphBuilder::BuildLoadNamedField(
5709f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    PropertyAccessInfo* info,
5710f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    HValue* checked_object) {
57112ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  // See if this is a load for an immutable property
57122ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (checked_object->ActualValue()->IsConstant() &&
57132ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      info->lookup()->IsCacheable() &&
57142ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      info->lookup()->IsReadOnly() && info->lookup()->IsDontDelete()) {
57152ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Handle<Object> object(
57162ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        HConstant::cast(checked_object->ActualValue())->handle(isolate()));
57172ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
57182ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    if (object->IsJSObject()) {
57192ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      LookupResult lookup(isolate());
57203484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      Handle<JSObject>::cast(object)->Lookup(info->name(), &lookup);
57212ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      Handle<Object> value(lookup.GetLazyValue(), isolate());
57222ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
57232ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      if (!value->IsTheHole()) {
57242ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        return New<HConstant>(value);
57252ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      }
57262ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    }
57272ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  }
57282ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
5729f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  HObjectAccess access = info->access();
5730f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (access.representation().IsDouble()) {
5731f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    // Load the heap number.
5732f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    checked_object = Add<HLoadNamedField>(
5733f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        checked_object, static_cast<HValue*>(NULL),
5734f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        access.WithRepresentation(Representation::Tagged()));
5735f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    // Load the double value from it.
5736f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    access = HObjectAccess::ForHeapNumberValue();
5737f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
57385924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org
57395924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  SmallMapList* map_list = info->field_maps();
57405924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  if (map_list->length() == 0) {
57415924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org    return New<HLoadNamedField>(checked_object, checked_object, access);
57425924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  }
57435924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org
57445924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  UniqueSet<Map>* maps = new(zone()) UniqueSet<Map>(map_list->length(), zone());
57455924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  for (int i = 0; i < map_list->length(); ++i) {
5746a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    maps->Add(Unique<Map>::CreateImmovable(map_list->at(i)), zone());
57475924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  }
5748f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  return New<HLoadNamedField>(
57495924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org      checked_object, checked_object, access, maps, info->field_type());
5750f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
5751f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
5752f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
5753a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHInstruction* HOptimizedGraphBuilder::BuildStoreNamedField(
57540a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    PropertyAccessInfo* info,
57551e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    HValue* checked_object,
57560a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    HValue* value) {
57570a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  bool transition_to_field = info->lookup()->IsTransition();
57580a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  // TODO(verwaest): Move this logic into PropertyAccessInfo.
5759e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  HObjectAccess field_access = info->access();
5760a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
5761a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  HStoreNamedField *instr;
5762f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (field_access.representation().IsDouble()) {
5763fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    HObjectAccess heap_number_access =
5764fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org        field_access.WithRepresentation(Representation::Tagged());
576557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    if (transition_to_field) {
5766a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      // The store requires a mutable HeapNumber to be allocated.
576757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      NoObservableSideEffectsScope no_side_effects(this);
57681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize);
576905150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org
5770d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      // TODO(hpayer): Allocation site pretenuring support.
5771d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      HInstruction* heap_number = Add<HAllocate>(heap_number_size,
5772eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org          HType::HeapObject(),
5773d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org          NOT_TENURED,
5774d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          HEAP_NUMBER_TYPE);
5775fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      AddStoreMapConstant(heap_number, isolate()->factory()->heap_number_map());
5776d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(),
57770a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                            value);
57781e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org      instr = New<HStoreNamedField>(checked_object->ActualValue(),
57791e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org                                    heap_number_access,
57800a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                                    heap_number);
578157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    } else {
5782a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      // Already holds a HeapNumber; load the box and write its value field.
578309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      HInstruction* heap_number = Add<HLoadNamedField>(
578409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org          checked_object, static_cast<HValue*>(NULL), heap_number_access);
5785d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      instr = New<HStoreNamedField>(heap_number,
5786d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                                    HObjectAccess::ForHeapNumberValue(),
578705150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org                                    value, STORE_TO_INITIALIZED_ENTRY);
578857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    }
5789a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  } else {
5790d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    if (field_access.representation().IsHeapObject()) {
5791d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      BuildCheckHeapObject(value);
5792d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    }
5793d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org
57949fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    if (!info->field_maps()->is_empty()) {
5795e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      ASSERT(field_access.representation().IsHeapObject());
5796af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org      value = Add<HCheckMaps>(value, info->field_maps());
5797e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    }
5798e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
5799fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    // This is a normal store.
580071ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org    instr = New<HStoreNamedField>(
580171ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org        checked_object->ActualValue(), field_access, value,
580271ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org        transition_to_field ? INITIALIZING_STORE : STORE_TO_INITIALIZED_ENTRY);
580357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  }
5804a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
580557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  if (transition_to_field) {
5806c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org    Handle<Map> transition(info->transition());
5807c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org    ASSERT(!transition->is_deprecated());
5808c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org    instr->SetTransition(Add<HConstant>(transition));
5809a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
5810a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return instr;
5811a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
5812a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5813a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
58140a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.orgbool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatible(
5815528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    PropertyAccessInfo* info) {
581657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  if (!CanInlinePropertyAccess(type_)) return false;
581757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
58180a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  // Currently only handle Type::Number as a polymorphic case.
581957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber
582057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  // instruction.
58210a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  if (type_->Is(Type::Number())) return false;
582257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
582357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  // Values are only compatible for monomorphic load if they all behave the same
582457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  // regarding value wrappers.
58250a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  if (type_->Is(Type::NumberOrString())) {
58260a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    if (!info->type_->Is(Type::NumberOrString())) return false;
582757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  } else {
58280a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    if (info->type_->Is(Type::NumberOrString())) return false;
582957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  }
5830528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
5831528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (!LookupDescriptor()) return false;
5832528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
5833528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (!lookup_.IsFound()) {
5834d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    return (!info->lookup_.IsFound() || info->has_holder()) &&
583557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org        map()->prototype() == info->map()->prototype();
5836528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
5837528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
5838d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  // Mismatch if the other access info found the property in the prototype
5839d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  // chain.
5840d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  if (info->has_holder()) return false;
5841d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
5842528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (lookup_.IsPropertyCallbacks()) {
58438297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    return accessor_.is_identical_to(info->accessor_) &&
58448297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org        api_holder_.is_identical_to(info->api_holder_);
5845528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
5846528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
5847528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (lookup_.IsConstant()) {
5848528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    return constant_.is_identical_to(info->constant_);
5849528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
5850528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
5851528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  ASSERT(lookup_.IsField());
5852528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (!info->lookup_.IsField()) return false;
5853528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
5854528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Representation r = access_.representation();
58550a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  if (IsLoad()) {
58560a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    if (!info->access_.representation().IsCompatibleForLoad(r)) return false;
58570a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  } else {
58580a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    if (!info->access_.representation().IsCompatibleForStore(r)) return false;
58590a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  }
5860528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (info->access_.offset() != access_.offset()) return false;
5861528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (info->access_.IsInobject() != access_.IsInobject()) return false;
58629fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  if (IsLoad()) {
58639fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    if (field_maps_.is_empty()) {
58649fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      info->field_maps_.Clear();
58659fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    } else if (!info->field_maps_.is_empty()) {
58669fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      for (int i = 0; i < field_maps_.length(); ++i) {
58679fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        info->field_maps_.AddMapIfMissing(field_maps_.at(i), info->zone());
58689fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      }
58699fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      info->field_maps_.Sort();
58709fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    }
58719fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  } else {
58729fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // We can only merge stores that agree on their field maps. The comparison
58739fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    // below is safe, since we keep the field maps sorted.
58749fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    if (field_maps_.length() != info->field_maps_.length()) return false;
58759fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    for (int i = 0; i < field_maps_.length(); ++i) {
58769fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      if (!field_maps_.at(i).is_identical_to(info->field_maps_.at(i))) {
58779fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        return false;
58789fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      }
58799fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    }
5880e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  }
5881528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  info->GeneralizeRepresentation(r);
58825924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  info->field_type_ = info->field_type_.Combine(field_type_);
5883bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  return true;
5884bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org}
5885bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
5886bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
5887528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgbool HOptimizedGraphBuilder::PropertyAccessInfo::LookupDescriptor() {
588857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  if (!type_->IsClass()) return true;
588957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  map()->LookupDescriptor(NULL, *name_, &lookup_);
589057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  return LoadResult(map());
5891528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org}
5892fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org
5893fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org
5894528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgbool HOptimizedGraphBuilder::PropertyAccessInfo::LoadResult(Handle<Map> map) {
58950a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  if (!IsLoad() && lookup_.IsProperty() &&
58960a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      (lookup_.IsReadOnly() || !lookup_.IsCacheable())) {
58970a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    return false;
58980a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  }
58990a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org
5900528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (lookup_.IsField()) {
5901e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    // Construct the object field access.
5902528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    access_ = HObjectAccess::ForField(map, &lookup_, name_);
5903e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
5904e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    // Load field map for heap objects.
59059fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    LoadFieldMaps(map);
5906528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  } else if (lookup_.IsPropertyCallbacks()) {
5907528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Handle<Object> callback(lookup_.GetValueFromMap(*map), isolate());
5908528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    if (!callback->IsAccessorPair()) return false;
59090a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    Object* raw_accessor = IsLoad()
59100a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org        ? Handle<AccessorPair>::cast(callback)->getter()
59110a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org        : Handle<AccessorPair>::cast(callback)->setter();
59120a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    if (!raw_accessor->IsJSFunction()) return false;
59130a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    Handle<JSFunction> accessor = handle(JSFunction::cast(raw_accessor));
59148297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    if (accessor->shared()->IsApiFunction()) {
59158297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      CallOptimization call_optimization(accessor);
5916ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org      if (call_optimization.is_simple_api_call()) {
5917ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org        CallOptimization::HolderLookup holder_lookup;
5918ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org        Handle<Map> receiver_map = this->map();
5919ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org        api_holder_ = call_optimization.LookupHolderOfExpectedType(
5920ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org            receiver_map, &holder_lookup);
59218297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      }
59228297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    }
5923c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    accessor_ = accessor;
5924528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  } else if (lookup_.IsConstant()) {
5925528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    constant_ = handle(lookup_.GetConstantFromMap(*map), isolate());
5926528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
5927fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org
5928528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  return true;
5929528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org}
5930528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
5931528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
59329fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.orgvoid HOptimizedGraphBuilder::PropertyAccessInfo::LoadFieldMaps(
59339fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<Map> map) {
59345924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  // Clear any previously collected field maps/type.
5935a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  field_maps_.Clear();
59365924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  field_type_ = HType::Tagged();
5937a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org
5938e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  // Figure out the field type from the accessor map.
59399fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<HeapType> field_type(lookup_.GetFieldTypeFromMap(*map), isolate());
5940e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
59419fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  // Collect the (stable) maps from the field type.
59429fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  int num_field_maps = field_type->NumClasses();
5943a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  if (num_field_maps == 0) return;
59449fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  ASSERT(access_.representation().IsHeapObject());
59459fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  field_maps_.Reserve(num_field_maps, zone());
59469fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  HeapType::Iterator<Map> it = field_type->Classes();
59479fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  while (!it.Done()) {
59489fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    Handle<Map> field_map = it.Current();
59499fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    if (!field_map->is_stable()) {
59509fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      field_maps_.Clear();
59519fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      return;
5952e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    }
59539fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    field_maps_.Add(field_map, zone());
59549fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    it.Advance();
5955e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  }
59569fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  field_maps_.Sort();
59579fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  ASSERT_EQ(num_field_maps, field_maps_.length());
59589fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org
59595924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  // Determine field HType from field HeapType.
5960eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org  field_type_ = HType::FromType<HeapType>(field_type);
5961eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org  ASSERT(field_type_.IsHeapObject());
59625924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org
59639fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  // Add dependency on the map that introduced the field.
59649fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Map::AddDependentCompilationInfo(
59659fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      handle(lookup_.GetFieldOwnerFromMap(*map), isolate()),
59669fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      DependentCode::kFieldTypeGroup, top_info());
5967e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org}
5968e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
5969e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
5970528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgbool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() {
597157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  Handle<Map> map = this->map();
597257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
5973528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  while (map->prototype()->IsJSObject()) {
5974528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    holder_ = handle(JSObject::cast(map->prototype()));
5975c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    if (holder_->map()->is_deprecated()) {
5976c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org      JSObject::TryMigrateInstance(holder_);
5977c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    }
5978528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    map = Handle<Map>(holder_->map());
59790a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    if (!CanInlinePropertyAccess(ToType(map))) {
5980528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      lookup_.NotFound();
5981528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      return false;
5982b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    }
5983528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    map->LookupDescriptor(*holder_, *name_, &lookup_);
5984528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    if (lookup_.IsFound()) return LoadResult(map);
5985b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  }
5986528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  lookup_.NotFound();
5987528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  return true;
5988528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org}
5989fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org
5990bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
59910a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.orgbool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessMonomorphic() {
599257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  if (!CanInlinePropertyAccess(type_)) return false;
59930a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  if (IsJSObjectFieldAccessor()) return IsLoad();
5994528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (!LookupDescriptor()) return false;
59950a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  if (lookup_.IsFound()) {
59960a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    if (IsLoad()) return true;
59970a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    return !lookup_.IsReadOnly() && lookup_.IsCacheable();
59980a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  }
59990a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  if (!LookupInPrototypes()) return false;
60000a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  if (IsLoad()) return true;
60010a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org
60020a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  if (lookup_.IsPropertyCallbacks()) return true;
60030a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  Handle<Map> map = this->map();
60040a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  map->LookupTransition(NULL, *name_, &lookup_);
6005bfd1d202fb7cd6d54d956414bad9f75a995d0f65machenbach@chromium.org  if (lookup_.IsTransitionToField() && map->unused_property_fields() > 0) {
6006e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    // Construct the object field access.
6007e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    access_ = HObjectAccess::ForField(map, &lookup_, name_);
6008e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
6009e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    // Load field map for heap objects.
60109fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org    LoadFieldMaps(transition());
60110a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    return true;
60120a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  }
60130a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  return false;
6014528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org}
6015528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
6016bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
60170a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.orgbool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessAsMonomorphic(
6018528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    SmallMapList* types) {
60190a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  ASSERT(type_->Is(ToType(types->first())));
60200a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  if (!CanAccessMonomorphic()) return false;
60210a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  STATIC_ASSERT(kMaxLoadPolymorphism == kMaxStorePolymorphism);
6022528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (types->length() > kMaxLoadPolymorphism) return false;
6023bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
602457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  HObjectAccess access = HObjectAccess::ForMap();  // bogus default
602557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  if (GetJSObjectFieldAccess(&access)) {
6026528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    for (int i = 1; i < types->length(); ++i) {
602757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      PropertyAccessInfo test_info(
60280a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org          builder_, access_type_, ToType(types->at(i)), name_);
602957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      HObjectAccess test_access = HObjectAccess::ForMap();  // bogus default
603057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      if (!test_info.GetJSObjectFieldAccess(&test_access)) return false;
603157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      if (!access.Equals(test_access)) return false;
6032528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    }
6033528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    return true;
6034528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
6035fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
60360a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  // Currently only handle Type::Number as a polymorphic case.
603757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber
603857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  // instruction.
60390a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  if (type_->Is(Type::Number())) return false;
60400a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org
60410a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  // Multiple maps cannot transition to the same target map.
60420a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  ASSERT(!IsLoad() || !lookup_.IsTransition());
60430a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  if (lookup_.IsTransition() && types->length() > 1) return false;
604457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
6045528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  for (int i = 1; i < types->length(); ++i) {
60460a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    PropertyAccessInfo test_info(
60470a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org        builder_, access_type_, ToType(types->at(i)), name_);
60480a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    if (!test_info.IsCompatible(this)) return false;
6049528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
6050528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
6051528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  return true;
6052fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org}
6053fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org
6054fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org
60550a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.orgstatic bool NeedsWrappingFor(Type* type, Handle<JSFunction> target) {
60560a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  return type->Is(Type::NumberOrString()) &&
6057486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      target->shared()->strict_mode() == SLOPPY &&
605857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      !target->shared()->native();
605957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org}
606057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
606157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
60628297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.orgHInstruction* HOptimizedGraphBuilder::BuildMonomorphicAccess(
6063528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    PropertyAccessInfo* info,
6064528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    HValue* object,
606557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    HValue* checked_object,
60668297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    HValue* value,
6067528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    BailoutId ast_id,
6068528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    BailoutId return_id,
6069528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    bool can_inline_accessor) {
6070594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
60718e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  HObjectAccess access = HObjectAccess::ForMap();  // bogus default
60728e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  if (info->GetJSObjectFieldAccess(&access)) {
60738297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    ASSERT(info->IsLoad());
60748297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    return New<HLoadNamedField>(object, checked_object, access);
6075528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
6076528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
6077528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HValue* checked_holder = checked_object;
6078528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (info->has_holder()) {
6079528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Handle<JSObject> prototype(JSObject::cast(info->map()->prototype()));
6080528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    checked_holder = BuildCheckPrototypeMaps(prototype, info->holder());
6081528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
6082528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
60838297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  if (!info->lookup()->IsFound()) {
60848297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    ASSERT(info->IsLoad());
60858297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    return graph()->GetConstantUndefined();
6086528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
6087528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
60888297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  if (info->lookup()->IsField()) {
60898297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    if (info->IsLoad()) {
6090f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      return BuildLoadNamedField(info, checked_holder);
609157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    } else {
60928297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      return BuildStoreNamedField(info, checked_object, value);
6093528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    }
6094528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
6095528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
60968297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  if (info->lookup()->IsTransition()) {
60978297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    ASSERT(!info->IsLoad());
60988297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    return BuildStoreNamedField(info, checked_object, value);
60990a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  }
61000a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org
61010a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  if (info->lookup()->IsPropertyCallbacks()) {
61028297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    Push(checked_object);
61038297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    int argument_count = 1;
61048297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    if (!info->IsLoad()) {
61058297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      argument_count = 2;
61068297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      Push(value);
61078297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    }
61088297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org
61090a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    if (NeedsWrappingFor(info->type(), info->accessor())) {
61100a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      HValue* function = Add<HConstant>(info->accessor());
61118297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      PushArgumentsFromEnvironment(argument_count);
61128297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      return New<HCallFunction>(function, argument_count, WRAP_AND_CALL);
61138297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    } else if (FLAG_inline_accessors && can_inline_accessor) {
61148297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      bool success = info->IsLoad()
61158297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org          ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id)
611625530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org          : TryInlineSetter(
611725530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org              info->accessor(), info->map(), ast_id, return_id, value);
61185b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      if (success || HasStackOverflow()) return NULL;
61190a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    }
61208297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org
61218297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    PushArgumentsFromEnvironment(argument_count);
61228297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    return BuildCallConstantFunction(info->accessor(), argument_count);
61230a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  }
61240a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org
61258297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  ASSERT(info->lookup()->IsConstant());
61268297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  if (info->IsLoad()) {
61278297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    return New<HConstant>(info->constant());
61288297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  } else {
61290a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant()));
61300a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  }
61310a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org}
61320a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org
61330a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org
61348297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.orgvoid HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess(
61358297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    PropertyAccessType access_type,
61363d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    BailoutId ast_id,
6137528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    BailoutId return_id,
6138fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org    HValue* object,
61398297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    HValue* value,
6140fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org    SmallMapList* types,
6141fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org    Handle<String> name) {
6142594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Something did not match; must use a polymorphic load.
6143594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  int count = 0;
6144594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  HBasicBlock* join = NULL;
614557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  HBasicBlock* number_block = NULL;
614657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  bool handled_string = false;
614757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
614857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  bool handle_smi = false;
61498297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  STATIC_ASSERT(kMaxLoadPolymorphism == kMaxStorePolymorphism);
6150594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) {
61518297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    PropertyAccessInfo info(this, access_type, ToType(types->at(i)), name);
61520a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    if (info.type()->Is(Type::String())) {
615357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      if (handled_string) continue;
615457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      handled_string = true;
615557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    }
61560a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    if (info.CanAccessMonomorphic()) {
615757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      count++;
61580a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      if (info.type()->Is(Type::Number())) {
615957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org        handle_smi = true;
616057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org        break;
6161594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      }
616257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    }
616357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  }
6164594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
616557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  count = 0;
616657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  HControlInstruction* smi_check = NULL;
616757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  handled_string = false;
6168594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
616957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) {
61708297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    PropertyAccessInfo info(this, access_type, ToType(types->at(i)), name);
61710a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    if (info.type()->Is(Type::String())) {
617257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      if (handled_string) continue;
617357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      handled_string = true;
617457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    }
61750a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    if (!info.CanAccessMonomorphic()) continue;
617657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
617757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    if (count == 0) {
617857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      join = graph()->CreateBasicBlock();
617957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      if (handle_smi) {
618057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org        HBasicBlock* empty_smi_block = graph()->CreateBasicBlock();
618157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org        HBasicBlock* not_smi_block = graph()->CreateBasicBlock();
618257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org        number_block = graph()->CreateBasicBlock();
618357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org        smi_check = New<HIsSmiAndBranch>(
618457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org            object, empty_smi_block, not_smi_block);
618557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org        FinishCurrentBlock(smi_check);
6186f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        GotoNoSimulate(empty_smi_block, number_block);
618757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org        set_current_block(not_smi_block);
6188594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      } else {
618957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org        BuildCheckHeapObject(object);
6190594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      }
619157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    }
619257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    ++count;
619357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    HBasicBlock* if_true = graph()->CreateBasicBlock();
619457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    HBasicBlock* if_false = graph()->CreateBasicBlock();
619557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    HUnaryControlInstruction* compare;
6196594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
619757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    HValue* dependency;
61980a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    if (info.type()->Is(Type::Number())) {
619957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      Handle<Map> heap_number_map = isolate()->factory()->heap_number_map();
6200052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org      compare = New<HCompareMap>(object, heap_number_map, if_true, if_false);
620157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      dependency = smi_check;
62020a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    } else if (info.type()->Is(Type::String())) {
620357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      compare = New<HIsStringAndBranch>(object, if_true, if_false);
620457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      dependency = compare;
620557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    } else {
6206052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org      compare = New<HCompareMap>(object, info.map(), if_true, if_false);
620757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      dependency = compare;
6208594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
620957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    FinishCurrentBlock(compare);
621057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
62110a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    if (info.type()->Is(Type::Number())) {
6212f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      GotoNoSimulate(if_true, number_block);
621357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      if_true = number_block;
621457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    }
621557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
621657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    set_current_block(if_true);
621757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
62188297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    HInstruction* access = BuildMonomorphicAccess(
62198297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org        &info, object, dependency, value, ast_id,
622057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org        return_id, FLAG_polymorphic_inlining);
62218297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org
62228297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    HValue* result = NULL;
62238297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    switch (access_type) {
62248297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      case LOAD:
62258297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org        result = access;
62268297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org        break;
62278297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      case STORE:
62288297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org        result = value;
62298297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org        break;
62308297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    }
62318297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org
62328297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    if (access == NULL) {
623357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      if (HasStackOverflow()) return;
623457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    } else {
62358297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      if (!access->IsLinked()) AddInstruction(access);
62368297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      if (!ast_context()->IsEffect()) Push(result);
623757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    }
623857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
623957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    if (current_block() != NULL) Goto(join);
624057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    set_current_block(if_false);
6241594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
6242594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
6243594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Finish up.  Unconditionally deoptimize if we've handled all the maps we
6244594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // know about and do not want to handle ones we've never seen.  Otherwise
6245594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // use a generic IC.
6246594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
6247f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    FinishExitWithHardDeoptimization("Uknown map in polymorphic access");
6248594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  } else {
6249f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    HInstruction* instr = BuildNamedGeneric(access_type, object, name, value);
6250f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    AddInstruction(instr);
6251f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (!ast_context()->IsEffect()) Push(access_type == LOAD ? instr : value);
6252594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
6253594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (join != NULL) {
625471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org      Goto(join);
6255594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    } else {
62563d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org      Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
6257594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
6258594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      return;
6259594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    }
6260594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
6261594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
6262594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  ASSERT(join != NULL);
6263f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (join->HasPredecessor()) {
6264f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    join->SetJoinId(ast_id);
6265f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    set_current_block(join);
6266f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
6267f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  } else {
6268f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    set_current_block(NULL);
6269f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
6270b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org}
6271fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org
6272fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org
6273639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.orgstatic bool ComputeReceiverTypes(Expression* expr,
6274639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                                 HValue* receiver,
62750a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                                 SmallMapList** t,
62760a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                                 Zone* zone) {
6277639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  SmallMapList* types = expr->GetReceiverTypes();
6278639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  *t = types;
6279639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  bool monomorphic = expr->IsMonomorphic();
6280639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  if (types != NULL && receiver->HasMonomorphicJSObjectType()) {
6281639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    Map* root_map = receiver->GetMonomorphicJSObjectMap()->FindRootMap();
6282639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    types->FilterForPossibleTransitions(root_map);
6283639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    monomorphic = types->length() == 1;
6284639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  }
62850a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  return monomorphic && CanInlinePropertyAccess(
62860a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      IC::MapToType<Type>(types->first(), zone));
62870a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org}
62880a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org
62890a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org
62900a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.orgstatic bool AreStringTypes(SmallMapList* types) {
62910a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  for (int i = 0; i < types->length(); i++) {
62920a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    if (types->at(i)->instance_type() >= FIRST_NONSTRING_TYPE) return false;
62930a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  }
62940a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  return true;
6295639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org}
6296a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6297a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6298639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.orgvoid HOptimizedGraphBuilder::BuildStore(Expression* expr,
6299639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                                        Property* prop,
6300639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                                        BailoutId ast_id,
6301639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                                        BailoutId return_id,
6302639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                                        bool is_uninitialized) {
6303639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  if (!prop->key()->IsPropertyName()) {
6304a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Keyed store.
63050a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    HValue* value = environment()->ExpressionStackAt(0);
630657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    HValue* key = environment()->ExpressionStackAt(1);
630757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    HValue* object = environment()->ExpressionStackAt(2);
63087b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    bool has_side_effects = false;
630971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    HandleKeyedElementAccess(object, key, value, expr,
6310f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                             STORE, &has_side_effects);
631157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    Drop(3);
63127b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    Push(value);
6313639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    Add<HSimulate>(return_id, REMOVABLE_SIMULATE);
63144f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    return ast_context()->ReturnValue(Pop());
6315a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
6316639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org
6317639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  // Named store.
63180a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  HValue* value = Pop();
63190a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  HValue* object = Pop();
6320639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org
6321639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  Literal* key = prop->key()->AsLiteral();
6322639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  Handle<String> name = Handle<String>::cast(key->value());
6323639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  ASSERT(!name.is_null());
6324639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org
63258297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  HInstruction* instr = BuildNamedAccess(STORE, ast_id, return_id, expr,
63268297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                         object, name, value, is_uninitialized);
63278297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  if (instr == NULL) return;
6328639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org
6329639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  if (!ast_context()->IsEffect()) Push(value);
6330639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  AddInstruction(instr);
6331639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  if (instr->HasObservableSideEffects()) {
6332639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
6333639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  }
6334639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  if (!ast_context()->IsEffect()) Drop(1);
6335639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  return ast_context()->ReturnValue(value);
6336639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org}
6337639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org
6338639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org
6339639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.orgvoid HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
6340639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  Property* prop = expr->target()->AsProperty();
6341639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  ASSERT(prop != NULL);
6342639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  CHECK_ALIVE(VisitForValue(prop->obj()));
6343639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  if (!prop->key()->IsPropertyName()) {
6344639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    CHECK_ALIVE(VisitForValue(prop->key()));
6345639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  }
6346639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  CHECK_ALIVE(VisitForValue(expr->value()));
6347639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  BuildStore(expr, prop, expr->id(),
6348639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org             expr->AssignmentId(), expr->IsUninitialized());
6349a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
6350a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6351a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
63525f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org// Because not every expression has a position and there is not common
63535f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org// superclass of Assignment and CountOperation, we cannot just pass the
63545f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org// owning expression instead of position and ast_id separately.
6355a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::HandleGlobalVariableAssignment(
6356a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    Variable* var,
6357a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    HValue* value,
6358a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    BailoutId ast_id) {
6359394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  LookupResult lookup(isolate());
6360f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, STORE);
6361c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  if (type == kUseCell) {
636241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    Handle<GlobalObject> global(current_info()->global_object());
6363b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    Handle<PropertyCell> cell(global->GetPropertyCell(&lookup));
6364e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    if (cell->type()->IsConstant()) {
63659fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      Handle<Object> constant = cell->type()->AsConstant()->Value();
6366f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      if (value->IsConstant()) {
6367f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        HConstant* c_value = HConstant::cast(value);
6368f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        if (!constant.is_identical_to(c_value->handle(isolate()))) {
6369f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          Add<HDeoptimize>("Constant global variable assignment",
6370f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                           Deoptimizer::EAGER);
6371f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        }
6372e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org      } else {
6373f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        HValue* c_constant = Add<HConstant>(constant);
6374f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        IfBuilder builder(this);
6375f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        if (constant->IsNumber()) {
6376f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          builder.If<HCompareNumericAndBranch>(value, c_constant, Token::EQ);
6377f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        } else {
6378f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          builder.If<HCompareObjectEqAndBranch>(value, c_constant);
6379f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        }
6380f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        builder.Then();
6381f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        builder.Else();
6382f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        Add<HDeoptimize>("Constant global variable assignment",
6383f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                         Deoptimizer::EAGER);
6384f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        builder.End();
6385e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org      }
6386e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    }
6387e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    HInstruction* instr =
6388e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org        Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails());
6389fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    if (instr->HasObservableSideEffects()) {
6390c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org      Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
6391fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
6392c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  } else {
639305150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org    HValue* global_object = Add<HLoadNamedField>(
639409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org        context(), static_cast<HValue*>(NULL),
639509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org        HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
639643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org    HStoreNamedGeneric* instr =
639743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org        Add<HStoreNamedGeneric>(global_object, var->name(),
6398486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org                                 value, function_strict_mode());
639971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    USE(instr);
6400c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    ASSERT(instr->HasObservableSideEffects());
6401c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
6402c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  }
6403a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
6404a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6405a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6406a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
6407a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Expression* target = expr->target();
6408a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  VariableProxy* proxy = target->AsVariableProxy();
6409a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Property* prop = target->AsProperty();
6410486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  ASSERT(proxy == NULL || prop == NULL);
6411a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6412a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // We have a second position recorded in the FullCodeGenerator to have
6413a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // type feedback for the binary operation.
6414a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  BinaryOperation* operation = expr->binary_operation();
6415a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6416486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  if (proxy != NULL) {
6417486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    Variable* var = proxy->var();
64187ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org    if (var->mode() == LET)  {
6419594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      return Bailout(kUnsupportedLetCompoundAssignment);
6420d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org    }
6421d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org
6422160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    CHECK_ALIVE(VisitForValue(operation));
6423a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6424486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    switch (var->location()) {
6425486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      case Variable::UNALLOCATED:
6426486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        HandleGlobalVariableAssignment(var,
6427486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org                                       Top(),
6428486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org                                       expr->AssignmentId());
6429486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        break;
6430486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
6431486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      case Variable::PARAMETER:
6432486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      case Variable::LOCAL:
6433486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        if (var->mode() == CONST_LEGACY)  {
6434594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          return Bailout(kUnsupportedConstCompoundAssignment);
64357ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org        }
6436d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org        BindIfLive(var, Top());
6437486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        break;
6438486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
6439486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      case Variable::CONTEXT: {
6440486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        // Bail out if we try to mutate a parameter value in a function
6441486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        // using the arguments object.  We do not (yet) correctly handle the
6442486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        // arguments property of the function.
644341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org        if (current_info()->scope()->arguments() != NULL) {
6444486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org          // Parameters will be allocated to context slots.  We have no
6445486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org          // direct way to detect that the variable is a parameter so we do
6446486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org          // a linear search of the parameter variables.
644741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org          int count = current_info()->scope()->num_parameters();
6448486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org          for (int i = 0; i < count; ++i) {
644941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org            if (var == current_info()->scope()->parameter(i)) {
6450594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org              Bailout(kAssignmentToParameterFunctionUsesArgumentsObject);
6451486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org            }
64527b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          }
64537b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        }
6454486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
64557ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org        HStoreContextSlot::Mode mode;
64567ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org
64577ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org        switch (var->mode()) {
64587ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org          case LET:
64597ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org            mode = HStoreContextSlot::kCheckDeoptimize;
64607ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org            break;
64617ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org          case CONST:
64627ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org            // This case is checked statically so no need to
64637ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org            // perform checks here
64647ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org            UNREACHABLE();
6465486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org          case CONST_LEGACY:
6466486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org            return ast_context()->ReturnValue(Pop());
64677ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org          default:
64687ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org            mode = HStoreContextSlot::kNoCheck;
64697ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org        }
64707ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org
6471486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        HValue* context = BuildContextChainWalk(var);
6472d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        HStoreContextSlot* instr = Add<HStoreContextSlot>(
6473d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org            context, var->index(), mode, Top());
6474c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        if (instr->HasObservableSideEffects()) {
6475c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org          Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
6476c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        }
6477486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        break;
64787b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      }
64797b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
6480486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      case Variable::LOOKUP:
6481594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        return Bailout(kCompoundAssignmentToLookupSlot);
6482a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
64834f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    return ast_context()->ReturnValue(Pop());
64845f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
6485a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else if (prop != NULL) {
6486639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    CHECK_ALIVE(VisitForValue(prop->obj()));
6487639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    HValue* object = Top();
6488639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    HValue* key = NULL;
6489528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    if ((!prop->IsFunctionPrototype() && !prop->key()->IsPropertyName()) ||
6490639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org        prop->IsStringAccess()) {
6491160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org      CHECK_ALIVE(VisitForValue(prop->key()));
6492639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org      key = Top();
6493639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    }
6494a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
649571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    CHECK_ALIVE(PushLoad(prop, object, key));
64967b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
6497639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    CHECK_ALIVE(VisitForValue(expr->value()));
6498639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    HValue* right = Pop();
6499639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    HValue* left = Pop();
65005f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
650125530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org    Push(BuildBinaryOperation(operation, left, right, PUSH_BEFORE_SIMULATE));
650225530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org
6503639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    BuildStore(expr, prop, expr->id(),
6504639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org               expr->AssignmentId(), expr->IsUninitialized());
6505a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
6506594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return Bailout(kInvalidLhsInCompoundAssignment);
6507a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
6508a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
6509a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6510a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6511a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) {
6512160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
6513160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
6514160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
6515a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  VariableProxy* proxy = expr->target()->AsVariableProxy();
6516a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Property* prop = expr->target()->AsProperty();
6517486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  ASSERT(proxy == NULL || prop == NULL);
6518a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6519a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (expr->is_compound()) {
6520a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    HandleCompoundAssignment(expr);
6521a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return;
6522a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
6523a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6524486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  if (prop != NULL) {
6525486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    HandlePropertyAssignment(expr);
6526486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  } else if (proxy != NULL) {
6527486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    Variable* var = proxy->var();
65287ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org
6529b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    if (var->mode() == CONST) {
6530d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org      if (expr->op() != Token::INIT_CONST) {
6531486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        return Bailout(kNonInitializerAssignmentToConst);
6532486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      }
6533486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    } else if (var->mode() == CONST_LEGACY) {
6534486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      if (expr->op() != Token::INIT_CONST_LEGACY) {
65357ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org        CHECK_ALIVE(VisitForValue(expr->value()));
65367ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org        return ast_context()->ReturnValue(Pop());
6537d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org      }
65387ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org
65397ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      if (var->IsStackAllocated()) {
65407ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org        // We insert a use of the old value to detect unsupported uses of const
65417ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org        // variables (e.g. initialization inside a loop).
65427ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org        HValue* old_value = environment()->Lookup(var);
65431510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        Add<HUseConst>(old_value);
6544d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com      }
6545d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org    }
6546d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org
6547594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    if (proxy->IsArguments()) return Bailout(kAssignmentToArguments);
65485f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
65495f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    // Handle the assignment.
6550486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    switch (var->location()) {
6551486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      case Variable::UNALLOCATED:
6552486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        CHECK_ALIVE(VisitForValue(expr->value()));
6553486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        HandleGlobalVariableAssignment(var,
6554486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org                                       Top(),
6555486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org                                       expr->AssignmentId());
6556486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        return ast_context()->ReturnValue(Pop());
6557486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
6558486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      case Variable::PARAMETER:
6559486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      case Variable::LOCAL: {
656064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org        // Perform an initialization check for let declared variables
656164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org        // or parameters.
656264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org        if (var->mode() == LET && expr->op() == Token::ASSIGN) {
656364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org          HValue* env_value = environment()->Lookup(var);
656464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org          if (env_value == graph()->GetConstantHole()) {
6565594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            return Bailout(kAssignmentToLetVariableBeforeInitialization);
656664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org          }
656764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org        }
6568486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        // We do not allow the arguments object to occur in a context where it
6569486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        // may escape, but assignments to stack-allocated locals are
6570486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        // permitted.
6571486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED));
6572486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        HValue* value = Pop();
6573d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org        BindIfLive(var, value);
6574486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        return ast_context()->ReturnValue(value);
6575486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      }
657683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
6577486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      case Variable::CONTEXT: {
6578486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        // Bail out if we try to mutate a parameter value in a function using
6579486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        // the arguments object.  We do not (yet) correctly handle the
6580486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        // arguments property of the function.
658141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org        if (current_info()->scope()->arguments() != NULL) {
6582486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org          // Parameters will rewrite to context slots.  We have no direct way
6583486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org          // to detect that the variable is a parameter.
658441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org          int count = current_info()->scope()->num_parameters();
6585486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org          for (int i = 0; i < count; ++i) {
658641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org            if (var == current_info()->scope()->parameter(i)) {
6587594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org              return Bailout(kAssignmentToParameterInArgumentsObject);
6588486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org            }
65897b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          }
65907b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        }
65917b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
6592486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        CHECK_ALIVE(VisitForValue(expr->value()));
659364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org        HStoreContextSlot::Mode mode;
659464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org        if (expr->op() == Token::ASSIGN) {
65957ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org          switch (var->mode()) {
65967ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org            case LET:
65977ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org              mode = HStoreContextSlot::kCheckDeoptimize;
65987ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org              break;
65997ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org            case CONST:
66007ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org              // This case is checked statically so no need to
66017ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org              // perform checks here
66027ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org              UNREACHABLE();
6603486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org            case CONST_LEGACY:
6604486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org              return ast_context()->ReturnValue(Pop());
66057ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org            default:
66067ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org              mode = HStoreContextSlot::kNoCheck;
66077ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org          }
66087ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org        } else if (expr->op() == Token::INIT_VAR ||
66097ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org                   expr->op() == Token::INIT_LET ||
6610486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org                   expr->op() == Token::INIT_CONST) {
66117ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org          mode = HStoreContextSlot::kNoCheck;
661264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org        } else {
6613486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org          ASSERT(expr->op() == Token::INIT_CONST_LEGACY);
66147ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org
66157ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org          mode = HStoreContextSlot::kCheckIgnoreAssignment;
661664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org        }
66177ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org
66187ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org        HValue* context = BuildContextChainWalk(var);
6619d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        HStoreContextSlot* instr = Add<HStoreContextSlot>(
6620d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org            context, var->index(), mode, Top());
6621c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        if (instr->HasObservableSideEffects()) {
6622c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org          Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
6623c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        }
6624486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        return ast_context()->ReturnValue(Pop());
6625486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      }
662683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
6627486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      case Variable::LOOKUP:
6628594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        return Bailout(kAssignmentToLOOKUPVariable);
6629a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
6630a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
6631594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return Bailout(kInvalidLeftHandSideInAssignment);
6632a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
6633a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
6634a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6635a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6636f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgvoid HOptimizedGraphBuilder::VisitYield(Yield* expr) {
6637f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  // Generators are not optimized, so we should never get here.
6638f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  UNREACHABLE();
6639f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org}
6640f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
6641f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
6642a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitThrow(Throw* expr) {
6643160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
6644160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
6645160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
66465f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // We don't optimize functions with invalid left-hand sides in
66475f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // assignments, count operations, or for-in.  Consequently throw can
66485f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // currently only occur in an effect context.
66495f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  ASSERT(ast_context()->IsEffect());
6650160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  CHECK_ALIVE(VisitForValue(expr->exception()));
6651a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6652a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HValue* value = environment()->Pop();
6653f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position());
66548d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  Add<HPushArguments>(value);
665509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  Add<HCallRuntime>(isolate()->factory()->empty_string(),
6656895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org                    Runtime::FunctionForId(Runtime::kHiddenThrow), 1);
6657c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  Add<HSimulate>(expr->id());
6658c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org
6659c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  // If the throw definitely exits the function, we can finish with a dummy
6660c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  // control flow at this point.  This is not the case if the throw is inside
6661c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  // an inlined function which may be replaced.
6662c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  if (call_context() == NULL) {
6663db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org    FinishExitCurrentBlock(New<HAbnormalExit>());
6664c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  }
6665a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
6666a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6667a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
66680f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.orgHInstruction* HGraphBuilder::AddLoadStringInstanceType(HValue* string) {
66690f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  if (string->IsConstant()) {
66700f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    HConstant* c_string = HConstant::cast(string);
66710f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    if (c_string->HasStringValue()) {
66720f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      return Add<HConstant>(c_string->StringValue()->map()->instance_type());
6673d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    }
667457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  }
6675f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  return Add<HLoadNamedField>(
6676f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      Add<HLoadNamedField>(string, static_cast<HValue*>(NULL),
6677f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                           HObjectAccess::ForMap()),
6678f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      static_cast<HValue*>(NULL), HObjectAccess::ForMapInstanceType());
66790f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org}
66800f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
66810f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
66820f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.orgHInstruction* HGraphBuilder::AddLoadStringLength(HValue* string) {
66830f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  if (string->IsConstant()) {
66840f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    HConstant* c_string = HConstant::cast(string);
66850f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    if (c_string->HasStringValue()) {
66860f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      return Add<HConstant>(c_string->StringValue()->length());
66870f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    }
66880f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  }
6689f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  return Add<HLoadNamedField>(string, static_cast<HValue*>(NULL),
6690f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                              HObjectAccess::ForStringLength());
6691a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
6692a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6693a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6694f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgHInstruction* HOptimizedGraphBuilder::BuildNamedGeneric(
6695f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    PropertyAccessType access_type,
6696a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    HValue* object,
6697a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    Handle<String> name,
6698f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    HValue* value,
66998297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    bool is_uninitialized) {
67008297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  if (is_uninitialized) {
6701f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    Add<HDeoptimize>("Insufficient type feedback for generic named access",
6702594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                     Deoptimizer::SOFT);
6703531dfe85209e15c3e292569c285a5be54910da7cjkummerow@chromium.org  }
6704f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (access_type == LOAD) {
6705f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    return New<HLoadNamedGeneric>(object, name);
6706f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  } else {
6707486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    return New<HStoreNamedGeneric>(object, name, value, function_strict_mode());
6708f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
6709a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
6710a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6711a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
671281cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org
6713f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgHInstruction* HOptimizedGraphBuilder::BuildKeyedGeneric(
6714f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    PropertyAccessType access_type,
6715f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    HValue* object,
6716f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    HValue* key,
6717f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    HValue* value) {
6718f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (access_type == LOAD) {
6719f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    return New<HLoadKeyedGeneric>(object, key);
6720f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  } else {
6721486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    return New<HStoreKeyedGeneric>(object, key, value, function_strict_mode());
6722f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
6723a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
6724a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6725a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
67261e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.orgLoadKeyedHoleMode HOptimizedGraphBuilder::BuildKeyedHoleMode(Handle<Map> map) {
6727906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  // Loads from a "stock" fast holey double arrays can elide the hole check.
6728906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE;
6729906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) &&
6730906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      isolate()->IsFastArrayConstructorPrototypeChainIntact()) {
6731906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate());
6732906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    Handle<JSObject> object_prototype = isolate()->initial_object_prototype();
6733594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    BuildCheckPrototypeMaps(prototype, object_prototype);
6734906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    load_mode = ALLOW_RETURN_HOLE;
6735906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org    graph()->MarkDependsOnEmptyArrayProtoElements();
6736906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org  }
6737906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org
67381e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  return load_mode;
67391e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org}
67401e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org
67411e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org
67421e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.orgHInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess(
67431e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    HValue* object,
67441e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    HValue* key,
67451e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    HValue* val,
67461e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    HValue* dependency,
67471e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    Handle<Map> map,
6748f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    PropertyAccessType access_type,
67491e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    KeyedAccessStoreMode store_mode) {
6750af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  HCheckMaps* checked_object = Add<HCheckMaps>(object, map, dependency);
67511e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  if (dependency) {
6752f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    checked_object->ClearDependsOnFlag(kElementsKind);
67531e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  }
67541e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org
6755f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (access_type == STORE && map->prototype()->IsJSObject()) {
6756e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    // monomorphic stores need a prototype chain check because shape
6757e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    // changes could allow callbacks on elements in the chain that
6758e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    // aren't compatible with monomorphic keyed stores.
6759e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    Handle<JSObject> prototype(JSObject::cast(map->prototype()));
6760e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    JSObject* holder = JSObject::cast(map->prototype());
6761e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    while (!holder->GetPrototype()->IsNull()) {
6762e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      holder = JSObject::cast(holder->GetPrototype());
6763e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    }
6764e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
6765e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    BuildCheckPrototypeMaps(prototype,
6766e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                            Handle<JSObject>(JSObject::cast(holder)));
6767e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  }
6768e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
67691e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map);
6770a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  return BuildUncheckedMonomorphicElementAccess(
67711e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org      checked_object, key, val,
67721e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org      map->instance_type() == JS_ARRAY_TYPE,
6773f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      map->elements_kind(), access_type,
67741e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org      load_mode, store_mode);
6775a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
6776a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6777a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6778a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad(
6779c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    HValue* object,
6780c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    HValue* key,
6781c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    HValue* val,
6782c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    SmallMapList* maps) {
6783c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  // For polymorphic loads of similar elements kinds (i.e. all tagged or all
6784c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  // double), always use the "worst case" code without a transition.  This is
6785c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  // much faster than transitioning the elements to the worst case, trading a
6786c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  // HTransitionElements for a HCheckMaps, and avoiding mutation of the array.
6787c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  bool has_double_maps = false;
6788c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  bool has_smi_or_object_maps = false;
6789c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  bool has_js_array_access = false;
6790c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  bool has_non_js_array_access = false;
6791ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org  bool has_seen_holey_elements = false;
6792c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  Handle<Map> most_general_consolidated_map;
6793c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  for (int i = 0; i < maps->length(); ++i) {
6794c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    Handle<Map> map = maps->at(i);
67954a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    if (!map->IsJSObjectMap()) return NULL;
6796c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    // Don't allow mixing of JSArrays with JSObjects.
6797c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    if (map->instance_type() == JS_ARRAY_TYPE) {
6798c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org      if (has_non_js_array_access) return NULL;
6799c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org      has_js_array_access = true;
6800c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    } else if (has_js_array_access) {
6801c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org      return NULL;
6802c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    } else {
6803c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org      has_non_js_array_access = true;
6804c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    }
6805c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    // Don't allow mixed, incompatible elements kinds.
6806c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    if (map->has_fast_double_elements()) {
6807c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org      if (has_smi_or_object_maps) return NULL;
6808c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org      has_double_maps = true;
6809c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    } else if (map->has_fast_smi_or_object_elements()) {
6810c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org      if (has_double_maps) return NULL;
6811c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org      has_smi_or_object_maps = true;
6812c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    } else {
6813c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org      return NULL;
6814c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    }
6815ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org    // Remember if we've ever seen holey elements.
6816ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org    if (IsHoleyElementsKind(map->elements_kind())) {
6817ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org      has_seen_holey_elements = true;
6818ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org    }
6819c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    // Remember the most general elements kind, the code for its load will
6820c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    // properly handle all of the more specific cases.
6821c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    if ((i == 0) || IsMoreGeneralElementsKindTransition(
6822c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org            most_general_consolidated_map->elements_kind(),
6823c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org            map->elements_kind())) {
6824c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org      most_general_consolidated_map = map;
6825c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    }
6826c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  }
6827c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  if (!has_double_maps && !has_smi_or_object_maps) return NULL;
6828c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org
6829052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org  HCheckMaps* checked_object = Add<HCheckMaps>(object, maps);
6830ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org  // FAST_ELEMENTS is considered more general than FAST_HOLEY_SMI_ELEMENTS.
6831ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org  // If we've seen both, the consolidated load must use FAST_HOLEY_ELEMENTS.
6832ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org  ElementsKind consolidated_elements_kind = has_seen_holey_elements
6833ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org      ? GetHoleyElementsKind(most_general_consolidated_map->elements_kind())
6834ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org      : most_general_consolidated_map->elements_kind();
6835c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  HInstruction* instr = BuildUncheckedMonomorphicElementAccess(
68361e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org      checked_object, key, val,
6837a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE,
6838ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org      consolidated_elements_kind,
6839f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      LOAD, NEVER_RETURN_HOLE, STANDARD_STORE);
6840c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  return instr;
6841c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org}
6842c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org
6843c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org
6844a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
6845a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    HValue* object,
6846a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    HValue* key,
6847a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    HValue* val,
68484a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    SmallMapList* maps,
6849f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    PropertyAccessType access_type,
68507bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org    KeyedAccessStoreMode store_mode,
6851a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    bool* has_side_effects) {
68527b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  *has_side_effects = false;
68531510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  BuildCheckHeapObject(object);
68547b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
6855f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (access_type == LOAD) {
6856c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    HInstruction* consolidated_load =
6857c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org        TryBuildConsolidatedElementLoad(object, key, val, maps);
6858c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    if (consolidated_load != NULL) {
6859c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org      *has_side_effects |= consolidated_load->HasObservableSideEffects();
6860c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org      return consolidated_load;
6861c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org    }
6862c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org  }
6863c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org
6864394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Elements_kind transition support.
6865394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  MapHandleList transition_target(maps->length());
6866394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Collect possible transition targets.
6867394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  MapHandleList possible_transitioned_maps(maps->length());
68687b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  for (int i = 0; i < maps->length(); ++i) {
6869394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Handle<Map> map = maps->at(i);
6870394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    ElementsKind elements_kind = map->elements_kind();
6871830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    if (IsFastElementsKind(elements_kind) &&
6872830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org        elements_kind != GetInitialFastElementsKind()) {
6873394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      possible_transitioned_maps.Add(map);
687444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    }
6875fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    if (elements_kind == SLOPPY_ARGUMENTS_ELEMENTS) {
6876fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      HInstruction* result = BuildKeyedGeneric(access_type, object, key, val);
6877fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      *has_side_effects = result->HasObservableSideEffects();
6878fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      return AddInstruction(result);
6879fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    }
688044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  }
6881394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Get transition target for each map (NULL == no transition).
6882394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  for (int i = 0; i < maps->length(); ++i) {
6883394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Handle<Map> map = maps->at(i);
6884394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Handle<Map> transitioned_map =
6885394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        map->FindTransitionedMap(&possible_transitioned_maps);
6886394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    transition_target.Add(transitioned_map);
6887394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
6888a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6889ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  MapHandleList untransitionable_maps(maps->length());
6890830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  HTransitionElementsKind* transition = NULL;
6891394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  for (int i = 0; i < maps->length(); ++i) {
6892394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Handle<Map> map = maps->at(i);
6893394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    ASSERT(map->IsMap());
6894394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    if (!transition_target.at(i).is_null()) {
6895830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      ASSERT(Map::IsValidElementsTransition(
6896830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org          map->elements_kind(),
6897830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org          transition_target.at(i)->elements_kind()));
6898d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      transition = Add<HTransitionElementsKind>(object, map,
68991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                                transition_target.at(i));
6900394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    } else {
6901ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      untransitionable_maps.Add(map);
6902394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    }
6903394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
6904394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
6905394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // If only one map is left after transitioning, handle this case
6906394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // monomorphically.
6907ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  ASSERT(untransitionable_maps.length() >= 1);
6908ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (untransitionable_maps.length() == 1) {
6909ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Handle<Map> untransitionable_map = untransitionable_maps[0];
69102efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    HInstruction* instr = NULL;
69114a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    if (untransitionable_map->has_slow_elements_kind() ||
69124a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org        !untransitionable_map->IsJSObjectMap()) {
6913f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      instr = AddInstruction(BuildKeyedGeneric(access_type, object, key, val));
69142efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    } else {
69157bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org      instr = BuildMonomorphicElementAccess(
6916f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          object, key, val, transition, untransitionable_map, access_type,
69177bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org          store_mode);
69182efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    }
6919c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    *has_side_effects |= instr->HasObservableSideEffects();
6920f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    return access_type == STORE ? NULL : instr;
6921394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
6922394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
69237b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  HBasicBlock* join = graph()->CreateBasicBlock();
6924a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6925ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  for (int i = 0; i < untransitionable_maps.length(); ++i) {
6926ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Handle<Map> map = untransitionable_maps[i];
69274a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    if (!map->IsJSObjectMap()) continue;
6928ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    ElementsKind elements_kind = map->elements_kind();
6929ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    HBasicBlock* this_map = graph()->CreateBasicBlock();
6930ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    HBasicBlock* other_map = graph()->CreateBasicBlock();
6931ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    HCompareMap* mapcompare =
6932052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org        New<HCompareMap>(object, map, this_map, other_map);
693371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    FinishCurrentBlock(mapcompare);
6934ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
6935ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    set_current_block(this_map);
6936ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    HInstruction* access = NULL;
69371e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    if (IsDictionaryElementsKind(elements_kind)) {
6938f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      access = AddInstruction(BuildKeyedGeneric(access_type, object, key, val));
6939ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    } else {
69401e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org      ASSERT(IsFastElementsKind(elements_kind) ||
6941895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org             IsExternalArrayElementsKind(elements_kind) ||
6942895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org             IsFixedTypedArrayElementsKind(elements_kind));
69431e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org      LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map);
69441e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org      // Happily, mapcompare is a checked object.
69451e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org      access = BuildUncheckedMonomorphicElementAccess(
69461e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org          mapcompare, key, val,
69471e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org          map->instance_type() == JS_ARRAY_TYPE,
6948f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          elements_kind, access_type,
69491e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org          load_mode,
69501e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org          store_mode);
6951ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    }
6952ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    *has_side_effects |= access->HasObservableSideEffects();
6953ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    // The caller will use has_side_effects and add a correct Simulate.
6954ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    access->SetFlag(HValue::kHasNoObservableSideEffects);
6955f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (access_type == LOAD) {
6956ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      Push(access);
69577b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    }
6958ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org    NoObservableSideEffectsScope scope(this);
695971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    GotoNoSimulate(join);
6960ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    set_current_block(other_map);
6961c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  }
69627b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
6963f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // Ensure that we visited at least one map above that goes to join. This is
6964f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // necessary because FinishExitWithHardDeoptimization does an AbnormalExit
6965f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // rather than joining the join block. If this becomes an issue, insert a
6966f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // generic access in the case length() == 0.
6967f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  ASSERT(join->predecessors()->length() > 0);
69687b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Deopt if none of the cases matched.
6969c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  NoObservableSideEffectsScope scope(this);
6970f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  FinishExitWithHardDeoptimization("Unknown map in polymorphic element access");
69717b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  set_current_block(join);
6972f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  return access_type == STORE ? NULL : Pop();
697344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org}
697444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
697544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
6976a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHValue* HOptimizedGraphBuilder::HandleKeyedElementAccess(
6977a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    HValue* obj,
6978a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    HValue* key,
6979a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    HValue* val,
6980a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    Expression* expr,
6981f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    PropertyAccessType access_type,
6982a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    bool* has_side_effects) {
69837b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  ASSERT(!expr->IsPropertyName());
69847b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  HInstruction* instr = NULL;
6985639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org
6986639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  SmallMapList* types;
69870a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  bool monomorphic = ComputeReceiverTypes(expr, obj, &types, zone());
6988639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org
6989e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  bool force_generic = false;
6990f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (access_type == STORE &&
6991f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      (monomorphic || (types != NULL && !types->is_empty()))) {
6992e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    // Stores can't be mono/polymorphic if their prototype chain has dictionary
6993e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    // elements. However a receiver map that has dictionary elements itself
6994e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    // should be left to normal mono/poly behavior (the other maps may benefit
6995e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    // from highly optimized stores).
6996e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    for (int i = 0; i < types->length(); i++) {
6997e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      Handle<Map> current_map = types->at(i);
6998e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      if (current_map->DictionaryElementsInPrototypeChainOnly()) {
6999e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org        force_generic = true;
7000e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org        monomorphic = false;
7001e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org        break;
7002e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      }
7003e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    }
7004e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  }
7005e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
7006639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  if (monomorphic) {
7007639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    Handle<Map> map = types->first();
700857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    if (map->has_slow_elements_kind() || !map->IsJSObjectMap()) {
7009f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      instr = AddInstruction(BuildKeyedGeneric(access_type, obj, key, val));
70102efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    } else {
70111510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      BuildCheckHeapObject(obj);
70127bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org      instr = BuildMonomorphicElementAccess(
7013f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          obj, key, val, NULL, map, access_type, expr->GetStoreMode());
70142efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    }
7015e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  } else if (!force_generic && (types != NULL && !types->is_empty())) {
70167b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    return HandlePolymorphicElementAccess(
7017f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        obj, key, val, types, access_type,
70187bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org        expr->GetStoreMode(), has_side_effects);
70197b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  } else {
7020f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (access_type == STORE) {
7021c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org      if (expr->IsAssignment() &&
7022c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org          expr->AsAssignment()->HasNoTypeInformation()) {
70233d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org        Add<HDeoptimize>("Insufficient type feedback for keyed store",
7024594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                         Deoptimizer::SOFT);
7025169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      }
70267b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    } else {
7027c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org      if (expr->AsProperty()->HasNoTypeInformation()) {
70283d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org        Add<HDeoptimize>("Insufficient type feedback for keyed load",
7029594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                         Deoptimizer::SOFT);
7030169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      }
703144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    }
7032f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    instr = AddInstruction(BuildKeyedGeneric(access_type, obj, key, val));
703344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  }
7034c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  *has_side_effects = instr->HasObservableSideEffects();
70357b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  return instr;
70363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}
70373a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
70383a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
7039a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() {
704028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  // Outermost function already has arguments on the stack.
704128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  if (function_state()->outer() == NULL) return;
704228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
704328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  if (function_state()->arguments_pushed()) return;
704428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
704528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  // Push arguments when entering inlined function.
704628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  HEnterInlined* entry = function_state()->entry();
704756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  entry->set_arguments_pushed();
704828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
7049b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  HArgumentsObject* arguments = entry->arguments_object();
7050b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  const ZoneList<HValue*>* arguments_values = arguments->arguments_values();
705128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
705228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  HInstruction* insert_after = entry;
705328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  for (int i = 0; i < arguments_values->length(); i++) {
705428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    HValue* argument = arguments_values->at(i);
70558d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    HInstruction* push_argument = New<HPushArguments>(argument);
705628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    push_argument->InsertAfter(insert_after);
705728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    insert_after = push_argument;
705828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  }
705928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
7060d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HArgumentsElements* arguments_elements = New<HArgumentsElements>(true);
706128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  arguments_elements->ClearFlag(HValue::kUseGVN);
706228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  arguments_elements->InsertAfter(insert_after);
706328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  function_state()->set_arguments_elements(arguments_elements);
706428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org}
706528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
706628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
7067a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgbool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) {
7068a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  VariableProxy* proxy = expr->obj()->AsVariableProxy();
7069a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (proxy == NULL) return false;
7070a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (!proxy->var()->IsStackAllocated()) return false;
7071a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) {
7072a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return false;
7073a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
7074a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
70755f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  HInstruction* result = NULL;
7076a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (expr->key()->IsPropertyName()) {
7077a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
707859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("length"))) return false;
707928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
708028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    if (function_state()->outer() == NULL) {
70811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      HInstruction* elements = Add<HArgumentsElements>(false);
7082d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      result = New<HArgumentsLength>(elements);
708328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    } else {
708428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org      // Number of arguments without receiver.
708528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org      int argument_count = environment()->
708628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org          arguments_environment()->parameter_count() - 1;
7087d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      result = New<HConstant>(argument_count);
708828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    }
7089a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
70909ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    Push(graph()->GetArgumentsObject());
7091639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    CHECK_ALIVE_OR_RETURN(VisitForValue(expr->key()), true);
7092a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    HValue* key = Pop();
70939ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    Drop(1);  // Arguments object.
709428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    if (function_state()->outer() == NULL) {
70951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      HInstruction* elements = Add<HArgumentsElements>(false);
70961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      HInstruction* length = Add<HArgumentsLength>(elements);
70971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      HInstruction* checked_key = Add<HBoundsCheck>(key, length);
7098db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org      result = New<HAccessArgumentsAt>(elements, length, checked_key);
709928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    } else {
710028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org      EnsureArgumentsArePushedForAccess();
710128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
710228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org      // Number of arguments without receiver.
710328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org      HInstruction* elements = function_state()->arguments_elements();
710428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org      int argument_count = environment()->
710528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org          arguments_environment()->parameter_count() - 1;
71061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      HInstruction* length = Add<HConstant>(argument_count);
71071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      HInstruction* checked_key = Add<HBoundsCheck>(key, length);
7108db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org      result = New<HAccessArgumentsAt>(elements, length, checked_key);
710928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    }
7110a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
71115f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  ast_context()->ReturnInstruction(result, expr->id());
7112a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return true;
7113a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
7114a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7115a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
71168297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.orgHInstruction* HOptimizedGraphBuilder::BuildNamedAccess(
71178297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    PropertyAccessType access,
71188297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    BailoutId ast_id,
71198297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    BailoutId return_id,
71208297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    Expression* expr,
71218297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    HValue* object,
71228297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    Handle<String> name,
71238297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    HValue* value,
71248297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    bool is_uninitialized) {
71258297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  SmallMapList* types;
71268297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  ComputeReceiverTypes(expr, object, &types, zone());
71278297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  ASSERT(types != NULL);
71288297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org
71298297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  if (types->length() > 0) {
71308297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    PropertyAccessInfo info(this, access, ToType(types->first()), name);
71318297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    if (!info.CanAccessAsMonomorphic(types)) {
71328297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      HandlePolymorphicNamedFieldAccess(
71338297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org          access, ast_id, return_id, object, value, types, name);
71348297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      return NULL;
71358297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    }
71368297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org
71378297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    HValue* checked_object;
71388297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    // Type::Number() is only supported by polymorphic load/call handling.
71398297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    ASSERT(!info.type()->Is(Type::Number()));
71408297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    BuildCheckHeapObject(object);
71418297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    if (AreStringTypes(types)) {
71428297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      checked_object =
71438297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org          Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING);
71448297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    } else {
7145052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org      checked_object = Add<HCheckMaps>(object, types);
71468297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    }
71478297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    return BuildMonomorphicAccess(
71488297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org        &info, object, checked_object, value, ast_id, return_id);
71498297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  }
71508297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org
7151f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  return BuildNamedGeneric(access, object, name, value, is_uninitialized);
71528297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org}
71538297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org
71548297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org
71553d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgvoid HOptimizedGraphBuilder::PushLoad(Property* expr,
71563d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                                      HValue* object,
715771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org                                      HValue* key) {
71583d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED);
71593d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  Push(object);
7160639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  if (key != NULL) Push(key);
716171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  BuildLoad(expr, expr->LoadId());
71623d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org}
7163a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7164a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
71653d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgvoid HOptimizedGraphBuilder::BuildLoad(Property* expr,
71663d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                                       BailoutId ast_id) {
7167a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HInstruction* instr = NULL;
7168528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (expr->IsStringAccess()) {
7169b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    HValue* index = Pop();
7170b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    HValue* string = Pop();
7171db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org    HInstruction* char_code = BuildStringCharCodeAt(string, index);
7172b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    AddInstruction(char_code);
7173db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org    instr = NewUncasted<HStringCharFromCode>(char_code);
7174378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
71759e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  } else if (expr->IsFunctionPrototype()) {
71769e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    HValue* function = Pop();
71771510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    BuildCheckHeapObject(function);
7178db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org    instr = New<HLoadFunctionPrototype>(function);
7179a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7180a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else if (expr->key()->IsPropertyName()) {
7181a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
7182528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    HValue* object = Pop();
7183a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
71848297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    instr = BuildNamedAccess(LOAD, ast_id, expr->LoadId(), expr,
71858297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                             object, name, NULL, expr->IsUninitialized());
71868297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    if (instr == NULL) return;
71878297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    if (instr->IsLinked()) return ast_context()->ReturnValue(instr);
7188a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7189a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
7190a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    HValue* key = Pop();
7191a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    HValue* obj = Pop();
71927b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
71937b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    bool has_side_effects = false;
71947b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    HValue* load = HandleKeyedElementAccess(
7195f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        obj, key, NULL, expr, LOAD, &has_side_effects);
71967b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    if (has_side_effects) {
71977b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      if (ast_context()->IsEffect()) {
71983d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org        Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
71997b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      } else {
72007b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        Push(load);
72013d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org        Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
72027b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        Drop(1);
72037b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      }
72047b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    }
72054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    return ast_context()->ReturnValue(load);
7206a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
72073d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  return ast_context()->ReturnInstruction(instr, ast_id);
72083d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org}
72093d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org
72103d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org
72113d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgvoid HOptimizedGraphBuilder::VisitProperty(Property* expr) {
72123d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  ASSERT(!HasStackOverflow());
72133d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  ASSERT(current_block() != NULL);
72143d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  ASSERT(current_block()->HasPredecessor());
72153d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org
72163d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  if (TryArgumentsAccess(expr)) return;
72173d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org
72183d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  CHECK_ALIVE(VisitForValue(expr->obj()));
7219528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if ((!expr->IsFunctionPrototype() && !expr->key()->IsPropertyName()) ||
7220639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org      expr->IsStringAccess()) {
7221639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    CHECK_ALIVE(VisitForValue(expr->key()));
7222639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  }
7223639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org
722471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  BuildLoad(expr, expr->id());
7225a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
7226a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7227a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7228af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.orgHInstruction* HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant) {
7229af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  HCheckMaps* check = Add<HCheckMaps>(
7230af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org      Add<HConstant>(constant), handle(constant->map()));
7231f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  check->ClearDependsOnFlag(kElementsKind);
7232ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org  return check;
7233594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
7234594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
7235594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
7236ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.orgHInstruction* HGraphBuilder::BuildCheckPrototypeMaps(Handle<JSObject> prototype,
7237ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org                                                     Handle<JSObject> holder) {
7238202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  while (holder.is_null() || !prototype.is_identical_to(holder)) {
7239af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    BuildConstantMapCheck(prototype);
7240202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    Object* next_prototype = prototype->GetPrototype();
7241202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    if (next_prototype->IsNull()) return NULL;
7242202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    CHECK(next_prototype->IsJSObject());
7243202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    prototype = handle(JSObject::cast(next_prototype));
7244594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  }
7245af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  return BuildConstantMapCheck(prototype);
7246594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org}
7247594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
7248594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
7249a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder,
7250a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                                   Handle<Map> receiver_map) {
7251e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (!holder.is_null()) {
72526bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org    Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype()));
7253594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    BuildCheckPrototypeMaps(prototype, holder);
7254e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  }
7255e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org}
7256e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
7257e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
725826ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.orgHInstruction* HOptimizedGraphBuilder::NewPlainFunctionCall(
725926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org    HValue* fun, int argument_count, bool pass_argument_count) {
726026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  return New<HCallJSFunction>(
726126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org      fun, argument_count, pass_argument_count);
726226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org}
726326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org
726426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org
726526ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.orgHInstruction* HOptimizedGraphBuilder::NewArgumentAdaptorCall(
726626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org    HValue* fun, HValue* context,
726726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org    int argument_count, HValue* expected_param_count) {
726826ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  CallInterfaceDescriptor* descriptor =
726926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org      isolate()->call_descriptor(Isolate::ArgumentAdaptorCall);
727026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org
727126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  HValue* arity = Add<HConstant>(argument_count - 1);
727226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org
727326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  HValue* op_vals[] = { fun, context, arity, expected_param_count };
727426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org
727526ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  Handle<Code> adaptor =
727626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org      isolate()->builtins()->ArgumentsAdaptorTrampoline();
727726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  HConstant* adaptor_value = Add<HConstant>(adaptor);
727826ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org
727926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  return New<HCallWithDescriptor>(
728026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org      adaptor_value, argument_count, descriptor,
728126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org      Vector<HValue*>(op_vals, descriptor->environment_length()));
728226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org}
728326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org
728426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org
728526ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.orgHInstruction* HOptimizedGraphBuilder::BuildCallConstantFunction(
728626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org    Handle<JSFunction> jsfun, int argument_count) {
728726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  HValue* target = Add<HConstant>(jsfun);
728826ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  // For constant functions, we try to avoid calling the
728926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  // argument adaptor and instead call the function directly
729026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  int formal_parameter_count = jsfun->shared()->formal_parameter_count();
729126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  bool dont_adapt_arguments =
729226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org      (formal_parameter_count ==
729326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org       SharedFunctionInfo::kDontAdaptArgumentsSentinel);
729426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  int arity = argument_count - 1;
729526ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  bool can_invoke_directly =
729626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org      dont_adapt_arguments || formal_parameter_count == arity;
729726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  if (can_invoke_directly) {
7298a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    if (jsfun.is_identical_to(current_info()->closure())) {
7299a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      graph()->MarkRecursive();
7300a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    }
730126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org    return NewPlainFunctionCall(target, argument_count, dont_adapt_arguments);
730226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  } else {
730326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org    HValue* param_count_value = Add<HConstant>(formal_parameter_count);
730409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org    HValue* context = Add<HLoadNamedField>(
730509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org        target, static_cast<HValue*>(NULL),
730626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org        HObjectAccess::ForFunctionContextPointer());
730726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org    return NewArgumentAdaptorCall(target, context,
730826ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org        argument_count, param_count_value);
730926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  }
731026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  UNREACHABLE();
731126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  return NULL;
731226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org}
731326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org
731426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org
73155aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.orgclass FunctionSorter {
73165aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org public:
73175aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org  FunctionSorter(int index = 0, int ticks = 0, int size = 0)
73185aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org      : index_(index), ticks_(ticks), size_(size) { }
73195aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org
73205aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org  int index() const { return index_; }
73215aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org  int ticks() const { return ticks_; }
73225aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org  int size() const { return size_; }
73235aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org
73245aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org private:
73255aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org  int index_;
73265aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org  int ticks_;
73275aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org  int size_;
73285aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org};
73295aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org
73305aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org
73315aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.orginline bool operator<(const FunctionSorter& lhs, const FunctionSorter& rhs) {
73325aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org  int diff = lhs.ticks() - rhs.ticks();
73335aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org  if (diff != 0) return diff > 0;
73345aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org  return lhs.size() < rhs.size();
73355aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org}
73365aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org
73375aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org
7338a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::HandlePolymorphicCallNamed(
7339a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    Call* expr,
7340a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    HValue* receiver,
7341a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    SmallMapList* types,
7342a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    Handle<String> name) {
73434d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  int argument_count = expr->arguments()->length() + 1;  // Includes receiver.
73445aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org  FunctionSorter order[kMaxCallPolymorphism];
73456e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
73466e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  bool handle_smi = false;
7347a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  bool handled_string = false;
7348a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  int ordered_functions = 0;
73496e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
7350212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  for (int i = 0;
7351e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org       i < types->length() && ordered_functions < kMaxCallPolymorphism;
7352212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org       ++i) {
73530a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name);
73540a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    if (info.CanAccessMonomorphic() &&
7355a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        info.lookup()->IsConstant() &&
7356a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        info.constant()->IsJSFunction()) {
73570a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      if (info.type()->Is(Type::String())) {
7358a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        if (handled_string) continue;
7359a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        handled_string = true;
7360a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      }
7361a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant());
73620a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      if (info.type()->Is(Type::Number())) {
7363a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        handle_smi = true;
7364a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      }
7365a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      expr->set_target(target);
73665aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org      order[ordered_functions++] = FunctionSorter(
73675aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org          i, target->shared()->profiler_ticks(), InliningAstSize(target));
7368212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    }
7369212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  }
73704d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org
73715aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org  std::sort(order, order + ordered_functions);
73725aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org
73736e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HBasicBlock* number_block = NULL;
7374a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  HBasicBlock* join = NULL;
7375a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  handled_string = false;
7376a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  int count = 0;
73776e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
7378e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  for (int fn = 0; fn < ordered_functions; ++fn) {
73795aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org    int i = order[fn].index();
73800a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name);
73810a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    if (info.type()->Is(Type::String())) {
7382a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      if (handled_string) continue;
7383a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      handled_string = true;
7384a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    }
7385a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    // Reloads the target.
73860a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    info.CanAccessMonomorphic();
7387a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant());
7388a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org
7389a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    expr->set_target(target);
7390a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    if (count == 0) {
7391e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org      // Only needed once.
7392e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org      join = graph()->CreateBasicBlock();
7393e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org      if (handle_smi) {
7394e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org        HBasicBlock* empty_smi_block = graph()->CreateBasicBlock();
7395e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org        HBasicBlock* not_smi_block = graph()->CreateBasicBlock();
7396e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org        number_block = graph()->CreateBasicBlock();
7397e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org        FinishCurrentBlock(New<HIsSmiAndBranch>(
7398e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org                receiver, empty_smi_block, not_smi_block));
7399f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        GotoNoSimulate(empty_smi_block, number_block);
7400e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org        set_current_block(not_smi_block);
74016e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org      } else {
7402e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org        BuildCheckHeapObject(receiver);
74039cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org      }
7404e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org    }
7405a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    ++count;
7406e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org    HBasicBlock* if_true = graph()->CreateBasicBlock();
7407e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org    HBasicBlock* if_false = graph()->CreateBasicBlock();
7408e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org    HUnaryControlInstruction* compare;
7409e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org
7410a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    Handle<Map> map = info.map();
74110a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    if (info.type()->Is(Type::Number())) {
7412a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      Handle<Map> heap_number_map = isolate()->factory()->heap_number_map();
7413052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org      compare = New<HCompareMap>(receiver, heap_number_map, if_true, if_false);
74140a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    } else if (info.type()->Is(Type::String())) {
7415e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org      compare = New<HIsStringAndBranch>(receiver, if_true, if_false);
7416e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org    } else {
7417052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org      compare = New<HCompareMap>(receiver, map, if_true, if_false);
7418e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org    }
7419e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org    FinishCurrentBlock(compare);
74209cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org
74210a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    if (info.type()->Is(Type::Number())) {
7422f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      GotoNoSimulate(if_true, number_block);
7423e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org      if_true = number_block;
74246e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    }
7425a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org
7426e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org    set_current_block(if_true);
74276e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
7428a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    AddCheckPrototypeMaps(info.holder(), map);
7429a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org
7430a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    HValue* function = Add<HConstant>(expr->target());
7431a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    environment()->SetExpressionStackAt(0, function);
7432a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    Push(receiver);
7433a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    CHECK_ALIVE(VisitExpressions(expr->arguments()));
7434a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    bool needs_wrapping = NeedsWrappingFor(info.type(), target);
7435a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    bool try_inline = FLAG_polymorphic_inlining && !needs_wrapping;
7436a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    if (FLAG_trace_inlining && try_inline) {
743741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      Handle<JSFunction> caller = current_info()->closure();
7438212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org      SmartArrayPointer<char> caller_name =
7439212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org          caller->shared()->DebugName()->ToCString();
7440212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org      PrintF("Trying to inline the polymorphic call to %s from %s\n",
7441afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org             name->ToCString().get(),
7442afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org             caller_name.get());
7443212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    }
7444a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    if (try_inline && TryInlineCall(expr)) {
7445212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org      // Trying to inline will signal that we should bailout from the
7446212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org      // entire compilation by setting stack overflow on the visitor.
7447212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org      if (HasStackOverflow()) return;
7448212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    } else {
7449a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      // Since HWrapReceiver currently cannot actually wrap numbers and strings,
7450a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      // use the regular CallFunctionStub for method calls to wrap the receiver.
7451a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      // TODO(verwaest): Support creation of value wrappers directly in
7452a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      // HWrapReceiver.
7453a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      HInstruction* call = needs_wrapping
7454a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org          ? NewUncasted<HCallFunction>(
7455a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org              function, argument_count, WRAP_AND_CALL)
7456a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org          : BuildCallConstantFunction(target, argument_count);
745726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org      PushArgumentsFromEnvironment(argument_count);
7458212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org      AddInstruction(call);
7459a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      Drop(1);  // Drop the function.
7460212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org      if (!ast_context()->IsEffect()) Push(call);
7461a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
74629cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org
7463e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org    if (current_block() != NULL) Goto(join);
7464212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    set_current_block(if_false);
7465a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
7466a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
74674d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  // Finish up.  Unconditionally deoptimize if we've handled all the maps we
74684d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  // know about and do not want to handle ones we've never seen.  Otherwise
74694d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  // use a generic IC.
7470e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) {
7471f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    FinishExitWithHardDeoptimization("Unknown map in polymorphic call");
74724d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  } else {
7473a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    Property* prop = expr->expression()->AsProperty();
7474f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    HInstruction* function = BuildNamedGeneric(
7475f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        LOAD, receiver, name, NULL, prop->IsUninitialized());
7476a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    AddInstruction(function);
7477a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    Push(function);
7478a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
7479a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org
7480a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    environment()->SetExpressionStackAt(1, function);
7481a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    environment()->SetExpressionStackAt(0, receiver);
7482a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    CHECK_ALIVE(VisitExpressions(expr->arguments()));
7483a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org
7484a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    CallFunctionFlags flags = receiver->type().IsJSObject()
7485a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD;
7486a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    HInstruction* call = New<HCallFunction>(
7487a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        function, argument_count, flags);
7488a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org
748926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org    PushArgumentsFromEnvironment(argument_count);
74908541d77d2d2a96c3e430974b3027f29b2a8e4a68lrn@chromium.org
7491a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    Drop(1);  // Function.
7492a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org
74934d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    if (join != NULL) {
74944d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org      AddInstruction(call);
74954d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org      if (!ast_context()->IsEffect()) Push(call);
749671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org      Goto(join);
74974d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    } else {
74984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      return ast_context()->ReturnInstruction(call, expr->id());
7499c278c96bd6281dacdebe24cede7d454372362cadkmillikin@chromium.org    }
75005f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  }
75014d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org
75024d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  // We assume that control flow is always live after an expression.  So
75034d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  // even without predecessors to the join block, we set it as the exit
75044d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  // block and continue by adding instructions there.
75054d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  ASSERT(join != NULL);
75064d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  if (join->HasPredecessor()) {
7507160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    set_current_block(join);
75084d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org    join->SetJoinId(expr->id());
75094f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop());
7510160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  } else {
7511160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    set_current_block(NULL);
75124d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  }
7513a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
7514a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7515a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7516a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::TraceInline(Handle<JSFunction> target,
7517a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                         Handle<JSFunction> caller,
7518a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                         const char* reason) {
75198f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  if (FLAG_trace_inlining) {
752083e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org    SmartArrayPointer<char> target_name =
752183e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org        target->shared()->DebugName()->ToCString();
752283e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org    SmartArrayPointer<char> caller_name =
752383e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org        caller->shared()->DebugName()->ToCString();
75248f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    if (reason == NULL) {
7525afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org      PrintF("Inlined %s called from %s.\n", target_name.get(),
7526afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org             caller_name.get());
75278f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    } else {
75288f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      PrintF("Did not inline %s called from %s (%s).\n",
7529afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org             target_name.get(), caller_name.get(), reason);
75308f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    }
7531a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
7532a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
7533a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7534a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7535212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgstatic const int kNotInlinable = 1000000000;
7536212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
7537212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
7538a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgint HOptimizedGraphBuilder::InliningAstSize(Handle<JSFunction> target) {
7539212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  if (!FLAG_use_inlining) return kNotInlinable;
7540a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7541a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Precondition: call is monomorphic and we have found a target with the
7542a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // appropriate arity.
754341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  Handle<JSFunction> caller = current_info()->closure();
7544ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  Handle<SharedFunctionInfo> target_shared(target->shared());
7545a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
75460cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  // Always inline builtins marked for inlining.
75470cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  if (target->IsBuiltin()) {
75480cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    return target_shared->inline_builtin() ? 0 : kNotInlinable;
75490cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  }
75500cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
7551ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  if (target_shared->IsApiFunction()) {
7552ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org    TraceInline(target, caller, "target is api function");
7553ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org    return kNotInlinable;
7554ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  }
7555ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org
7556a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Do a quick check on source code length to avoid parsing large
7557a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // inlining candidates.
755888d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  if (target_shared->SourceSize() >
755988d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org      Min(FLAG_max_inlined_source_size, kUnlimitedMaxInlinedSourceSize)) {
7560ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    TraceInline(target, caller, "target text too big");
7561212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    return kNotInlinable;
7562a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
7563a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7564a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Target must be inlineable.
75650cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  if (!target_shared->IsInlineable()) {
7566ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    TraceInline(target, caller, "target not inlineable");
7567212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    return kNotInlinable;
75688f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  }
756956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  if (target_shared->dont_inline() || target_shared->dont_optimize()) {
7570b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    TraceInline(target, caller, "target contains unsupported syntax [early]");
7571212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org    return kNotInlinable;
7572b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  }
7573b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org
7574b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  int nodes_added = target_shared->ast_node_count();
7575212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  return nodes_added;
7576212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org}
7577212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
7578212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
7579e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.orgbool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target,
7580a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                       int arguments_count,
7581a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                       HValue* implicit_return_value,
7582a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                       BailoutId ast_id,
7583a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                       BailoutId return_id,
7584f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                       InliningKind inlining_kind,
7585f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                       HSourcePosition position) {
7586212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  int nodes_added = InliningAstSize(target);
7587212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  if (nodes_added == kNotInlinable) return false;
7588212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
758941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  Handle<JSFunction> caller = current_info()->closure();
7590212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
759188d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) {
7592b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    TraceInline(target, caller, "target AST is too large [early]");
7593b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    return false;
7594b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  }
7595a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7596ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // Don't inline deeper than the maximum number of inlining levels.
7597a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HEnvironment* env = environment();
759874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  int current_level = 1;
759974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  while (env->outer() != NULL) {
7600ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    if (current_level == FLAG_max_inlining_levels) {
7601ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      TraceInline(target, caller, "inline depth limit reached");
760274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org      return false;
760374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org    }
7604967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    if (env->outer()->frame_type() == JS_FUNCTION) {
7605659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      current_level++;
7606659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    }
760774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org    env = env->outer();
76088f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  }
7609a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7610a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Don't inline recursive functions.
7611394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  for (FunctionState* state = function_state();
7612394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com       state != NULL;
7613394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com       state = state->outer()) {
7614068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org    if (*state->compilation_info()->closure() == *target) {
7615394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      TraceInline(target, caller, "target is recursive");
7616394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      return false;
7617394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    }
76188f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  }
7619a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7620a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // We don't want to add more than a certain number of nodes from inlining.
762188d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  if (inlined_count_ > Min(FLAG_max_inlined_nodes_cumulative,
762288d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org                           kUnlimitedMaxInlinedNodesCumulative)) {
7623ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    TraceInline(target, caller, "cumulative AST node limit reached");
7624a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return false;
7625a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
7626a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7627a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Parse and allocate variables.
76285a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  CompilationInfo target_info(target, zone());
7629068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  Handle<SharedFunctionInfo> target_shared(target->shared());
7630e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (!Parser::Parse(&target_info) || !Scope::Analyze(&target_info)) {
7631ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (target_info.isolate()->has_pending_exception()) {
76328f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      // Parse or scope error, never optimize this function.
7633496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org      SetStackOverflow();
7634594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      target_shared->DisableOptimization(kParseScopeError);
7635496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org    }
7636ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    TraceInline(target, caller, "parse failure");
76378f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    return false;
76388f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  }
76398f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
76408f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  if (target_info.scope()->num_heap_slots() > 0) {
7641ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    TraceInline(target, caller, "target has context-allocated variables");
7642a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return false;
7643a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
76448f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  FunctionLiteral* function = target_info.function();
7645a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7646b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  // The following conditions must be checked again after re-parsing, because
7647b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  // earlier the information might not have been complete due to lazy parsing.
7648b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  nodes_added = function->ast_node_count();
764988d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) {
7650b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    TraceInline(target, caller, "target AST is too large [late]");
7651b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    return false;
7652b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  }
7653b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org  AstProperties::Flags* flags(function->flags());
76542c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org  if (flags->Contains(kDontInline) || function->dont_optimize()) {
7655b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    TraceInline(target, caller, "target contains unsupported syntax [late]");
7656a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return false;
7657a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
7658a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7659154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  // If the function uses the arguments object check that inlining of functions
7660154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  // with arguments object is enabled and the arguments-variable is
7661154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  // stack allocated.
7662659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  if (function->scope()->arguments() != NULL) {
7663154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    if (!FLAG_inline_arguments) {
7664154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org      TraceInline(target, caller, "target uses arguments object");
7665154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org      return false;
7666154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    }
7667154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org
7668154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    if (!function->scope()->arguments()->IsStackAllocated()) {
7669154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org      TraceInline(target,
7670154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org                  caller,
7671154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org                  "target uses non-stackallocated arguments object");
7672154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org      return false;
7673154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    }
7674a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
7675a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7676d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  // All declarations must be inlineable.
7677d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  ZoneList<Declaration*>* decls = target_info.scope()->declarations();
7678d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  int decl_count = decls->length();
7679d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  for (int i = 0; i < decl_count; ++i) {
7680d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com    if (!decls->at(i)->IsInlineable()) {
7681d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com      TraceInline(target, caller, "target has non-trivial declaration");
7682d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com      return false;
7683d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com    }
7684d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  }
7685a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7686a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Generate the deoptimization data for the unoptimized version of
7687a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // the target function if we don't already have it.
76888f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  if (!target_shared->has_deoptimization_support()) {
7689a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Note that we compile here using the same AST that we will use for
7690a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // generating the optimized inline code.
76918f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    target_info.EnableDeoptimizationSupport();
76928f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    if (!FullCodeGenerator::MakeCode(&target_info)) {
7693ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      TraceInline(target, caller, "could not generate deoptimization info");
76948f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      return false;
76958f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    }
76968432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    if (target_shared->scope_info() == ScopeInfo::Empty(isolate())) {
76974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      // The scope info might not have been set if a lazily compiled
76984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      // function is inlined before being called for the first time.
7699c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      Handle<ScopeInfo> target_scope_info =
77007028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org          ScopeInfo::Create(target_info.scope(), zone());
77014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      target_shared->set_scope_info(*target_scope_info);
77024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    }
77038f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    target_shared->EnableDeoptimizationSupport(*target_info.code());
7704a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org    target_shared->set_feedback_vector(*target_info.feedback_vector());
77058f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    Compiler::RecordFunctionCompilation(Logger::FUNCTION_TAG,
77068f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                                        &target_info,
77078f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                                        target_shared);
7708a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
7709a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
77108f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // ----------------------------------------------------------------
7711d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  // After this point, we've made a decision to inline this function (so
7712d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  // TryInline should always return true).
7713d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com
7714c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  // Type-check the inlined function.
77158f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  ASSERT(target_shared->has_deoptimization_support());
771641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  AstTyper::Run(&target_info);
7717c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
7718f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  int function_id = graph()->TraceInlinedFunction(target_shared, position);
7719f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
7720c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  // Save the pending call context. Set up new one for the inlined function.
7721394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // The function state is new-allocated because we need to delete it
7722394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // in two different places.
7723967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  FunctionState* target_state = new FunctionState(
7724f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      this, &target_info, inlining_kind, function_id);
7725a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
77264d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  HConstant* undefined = graph()->GetConstantUndefined();
7727e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org
77284d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  HEnvironment* inner_env =
77291c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org      environment()->CopyForInlining(target,
7730304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org                                     arguments_count,
77311c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                                     function,
773240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                                     undefined,
7733e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org                                     function_state()->inlining_kind());
7734935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org
77351510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HConstant* context = Add<HConstant>(Handle<Context>(target->context()));
7736c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  inner_env->BindContext(context);
773728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
7738b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  HArgumentsObject* arguments_object = NULL;
773928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
7740b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  // If the function uses arguments object create and bind one, also copy
7741b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  // current arguments values to use them for materialization.
774228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  if (function->scope()->arguments() != NULL) {
7743b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    ASSERT(function->scope()->arguments()->IsStackAllocated());
774428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    HEnvironment* arguments_env = inner_env->arguments_environment();
774528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    int arguments_count = arguments_env->parameter_count();
7746d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    arguments_object = Add<HArgumentsObject>(arguments_count);
7747b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    inner_env->Bind(function->scope()->arguments(), arguments_object);
774828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    for (int i = 0; i < arguments_count; i++) {
7749b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      arguments_object->AddArgument(arguments_env->Lookup(i), zone());
775028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    }
775128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  }
775228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
7753f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  // Capture the state before invoking the inlined function for deopt in the
7754f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  // inlined function. This simulate has no bailout-id since it's not directly
7755f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  // reachable for deopt, and is only used to capture the state. If the simulate
7756f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  // becomes reachable by merging, the ast id of the simulate merged into it is
7757f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  // adopted.
7758f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  Add<HSimulate>(BailoutId::None());
7759f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org
7760f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  current_block()->UpdateEnvironment(inner_env);
77611e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  Scope* saved_scope = scope();
77621e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  set_scope(target_info.scope());
776328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  HEnterInlined* enter_inlined =
7764f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org      Add<HEnterInlined>(return_id, target, arguments_count, function,
77651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                         function_state()->inlining_kind(),
77661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                         function->scope()->arguments(),
7767e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org                         arguments_object);
776828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  function_state()->set_entry(enter_inlined);
776928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
7770d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  VisitDeclarations(target_info.scope()->declarations());
77714d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  VisitStatements(function->body());
77721e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  set_scope(saved_scope);
7773a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (HasStackOverflow()) {
7774a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Bail out if the inline function did, as we cannot residualize a call
7775a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // instead.
7776ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    TraceInline(target, caller, "inline graph construction failed");
7777594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    target_shared->DisableOptimization(kInliningBailedOut);
7778ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    inline_bailout_ = true;
7779394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    delete target_state;
7780160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    return true;
7781a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
7782a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7783a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Update inlined nodes count.
7784a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  inlined_count_ += nodes_added;
7785a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7786c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  Handle<Code> unoptimized_code(target_shared->code());
778746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  ASSERT(unoptimized_code->kind() == Code::FUNCTION);
778846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Handle<TypeFeedbackInfo> type_info(
7789fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      TypeFeedbackInfo::cast(unoptimized_code->type_feedback_info()));
779046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  graph()->update_type_change_checksum(type_info->own_type_change_checksum());
779146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
7792ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  TraceInline(target, caller, NULL);
7793a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
77944d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  if (current_block() != NULL) {
7795471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    FunctionState* state = function_state();
7796471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) {
7797471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      // Falling off the end of an inlined construct call. In a test context the
7798471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      // return value will always evaluate to true, in a value context the
7799471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      // return value is the newly allocated receiver.
7800471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      if (call_context()->IsTest()) {
780171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org        Goto(inlined_test_context()->if_true(), state);
7802471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      } else if (call_context()->IsEffect()) {
780371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org        Goto(function_return(), state);
7804471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      } else {
7805471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org        ASSERT(call_context()->IsValue());
780671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org        AddLeaveInlined(implicit_return_value, state);
7807471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      }
7808471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    } else if (state->inlining_kind() == SETTER_CALL_RETURN) {
7809471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      // Falling off the end of an inlined setter call. The returned value is
7810471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      // never used, the value of an assignment is always the value of the RHS
7811471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      // of the assignment.
7812471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      if (call_context()->IsTest()) {
7813471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org        inlined_test_context()->ReturnValue(implicit_return_value);
7814471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      } else if (call_context()->IsEffect()) {
781571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org        Goto(function_return(), state);
7816471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      } else {
7817471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org        ASSERT(call_context()->IsValue());
781871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org        AddLeaveInlined(implicit_return_value, state);
7819471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      }
7820a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    } else {
7821471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      // Falling off the end of a normal inlined function. This basically means
7822471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      // returning undefined.
7823471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      if (call_context()->IsTest()) {
782471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org        Goto(inlined_test_context()->if_false(), state);
7825471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      } else if (call_context()->IsEffect()) {
782671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org        Goto(function_return(), state);
7827471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      } else {
7828471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org        ASSERT(call_context()->IsValue());
782971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org        AddLeaveInlined(undefined, state);
7830471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      }
7831a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
7832a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
7833a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7834a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Fix up the function exits.
78358f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  if (inlined_test_context() != NULL) {
78368f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    HBasicBlock* if_true = inlined_test_context()->if_true();
78378f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    HBasicBlock* if_false = inlined_test_context()->if_false();
7838e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
7839d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    HEnterInlined* entry = function_state()->entry();
7840d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
78418f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    // Pop the return test context from the expression context stack.
7842e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    ASSERT(ast_context() == inlined_test_context());
78438f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    ClearInlinedTestContext();
7844394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    delete target_state;
7845a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
78465f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    // Forward to the real test context.
7847e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    if (if_true->HasPredecessor()) {
7848d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      entry->RegisterReturnTarget(if_true, zone());
7849967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      if_true->SetJoinId(ast_id);
7850e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org      HBasicBlock* true_target = TestContext::cast(ast_context())->if_true();
785171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org      Goto(if_true, true_target, function_state());
7852e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    }
7853e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    if (if_false->HasPredecessor()) {
7854d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      entry->RegisterReturnTarget(if_false, zone());
7855967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      if_false->SetJoinId(ast_id);
7856e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org      HBasicBlock* false_target = TestContext::cast(ast_context())->if_false();
785771f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org      Goto(if_false, false_target, function_state());
7858e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    }
78593a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    set_current_block(NULL);
7860394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    return true;
7861a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7862160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  } else if (function_return()->HasPredecessor()) {
7863d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    function_state()->entry()->RegisterReturnTarget(function_return(), zone());
7864967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    function_return()->SetJoinId(ast_id);
78658f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    set_current_block(function_return());
7866160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  } else {
7867160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    set_current_block(NULL);
7868a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
7869394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  delete target_state;
7870a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return true;
7871a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
7872a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7873a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7874a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.orgbool HOptimizedGraphBuilder::TryInlineCall(Call* expr) {
7875e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  return TryInline(expr->target(),
7876304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org                   expr->arguments()->length(),
7877967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org                   NULL,
7878967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org                   expr->id(),
7879967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org                   expr->ReturnId(),
7880f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                   NORMAL_RETURN,
7881f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                   ScriptPositionToSourcePosition(expr->position()));
7882967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org}
7883967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org
7884967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org
7885a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgbool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr,
7886a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                                HValue* implicit_return_value) {
7887e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  return TryInline(expr->target(),
7888304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org                   expr->arguments()->length(),
7889471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                   implicit_return_value,
7890967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org                   expr->id(),
7891967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org                   expr->ReturnId(),
7892f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                   CONSTRUCT_CALL_RETURN,
7893f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                   ScriptPositionToSourcePosition(expr->position()));
7894967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org}
7895967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org
7896967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org
7897a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgbool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter,
78988297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                             Handle<Map> receiver_map,
78993d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                                             BailoutId ast_id,
79003d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                                             BailoutId return_id) {
79018297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  if (TryInlineApiGetter(getter, receiver_map, ast_id)) return true;
7902e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  return TryInline(getter,
7903ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org                   0,
7904ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org                   NULL,
79053d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                   ast_id,
79063d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org                   return_id,
7907f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                   GETTER_CALL_RETURN,
7908f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                   source_position());
7909ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org}
7910ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org
7911ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org
7912a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgbool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter,
791325530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org                                             Handle<Map> receiver_map,
7914b0deb658b04208a80c51265c6499f9eb564f1db3danno@chromium.org                                             BailoutId id,
7915b0deb658b04208a80c51265c6499f9eb564f1db3danno@chromium.org                                             BailoutId assignment_id,
7916a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                             HValue* implicit_return_value) {
791725530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org  if (TryInlineApiSetter(setter, receiver_map, id)) return true;
7918e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  return TryInline(setter,
7919471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                   1,
7920471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                   implicit_return_value,
7921b0deb658b04208a80c51265c6499f9eb564f1db3danno@chromium.org                   id, assignment_id,
7922f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                   SETTER_CALL_RETURN,
7923f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                   source_position());
7924471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org}
7925471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
7926471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
79273ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgbool HOptimizedGraphBuilder::TryInlineApply(Handle<JSFunction> function,
79283ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org                                            Call* expr,
79293ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org                                            int arguments_count) {
7930e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  return TryInline(function,
79316ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org                   arguments_count,
79326ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org                   NULL,
79336ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org                   expr->id(),
79346ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org                   expr->ReturnId(),
7935f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                   NORMAL_RETURN,
7936f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                   ScriptPositionToSourcePosition(expr->position()));
79376ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org}
79386ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org
79396ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org
7940a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.orgbool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr) {
794178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  if (!expr->target()->shared()->HasBuiltinFunctionId()) return false;
794278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  BuiltinFunctionId id = expr->target()->shared()->builtin_function_id();
794378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  switch (id) {
79441f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org    case kMathExp:
79451f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org      if (!FLAG_fast_math) break;
79461f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org      // Fall through if FLAG_fast_math.
794778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    case kMathRound:
79482e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    case kMathFloor:
794978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    case kMathAbs:
795078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    case kMathSqrt:
795178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    case kMathLog:
7952f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    case kMathClz32:
795378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      if (expr->arguments()->length() == 1) {
795478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org        HValue* argument = Pop();
7955a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        Drop(2);  // Receiver and function.
7956db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org        HInstruction* op = NewUncasted<HUnaryMathOperation>(argument, id);
795778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org        ast_context()->ReturnInstruction(op, expr->id());
795878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org        return true;
795978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      }
796078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      break;
7961ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    case kMathImul:
7962ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      if (expr->arguments()->length() == 2) {
7963ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org        HValue* right = Pop();
7964ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org        HValue* left = Pop();
7965a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        Drop(2);  // Receiver and function.
7966db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org        HInstruction* op = HMul::NewImul(zone(), context(), left, right);
7967ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org        ast_context()->ReturnInstruction(op, expr->id());
7968ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org        return true;
7969ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      }
7970ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      break;
797178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    default:
797278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      // Not supported for inlining yet.
797378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      break;
797478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  }
797578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  return false;
797678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org}
797778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
797878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
7979a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgbool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
7980a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    Call* expr,
79813ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org    HValue* receiver,
79823ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org    Handle<Map> receiver_map) {
7983a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Try to inline calls like Math.* as operations in the calling function.
79843ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  if (!expr->target()->shared()->HasBuiltinFunctionId()) return false;
79853ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  BuiltinFunctionId id = expr->target()->shared()->builtin_function_id();
79863ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  int argument_count = expr->arguments()->length() + 1;  // Plus receiver.
7987a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  switch (id) {
79880a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    case kStringCharCodeAt:
7989b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org    case kStringCharAt:
7990a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      if (argument_count == 2) {
79910a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        HValue* index = Pop();
79920a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        HValue* string = Pop();
7993a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        Drop(1);  // Function.
79942e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        HInstruction* char_code =
7995d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org            BuildStringCharCodeAt(string, index);
7996b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org        if (id == kStringCharCodeAt) {
7997b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org          ast_context()->ReturnInstruction(char_code, expr->id());
7998b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org          return true;
7999b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org        }
8000b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org        AddInstruction(char_code);
8001db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org        HInstruction* result = NewUncasted<HStringCharFromCode>(char_code);
80020a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        ast_context()->ReturnInstruction(result, expr->id());
80030a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        return true;
80040a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      }
80050a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      break;
8006b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org    case kStringFromCharCode:
8007a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      if (argument_count == 2) {
8008b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org        HValue* argument = Pop();
8009a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        Drop(2);  // Receiver and function.
8010db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org        HInstruction* result = NewUncasted<HStringCharFromCode>(argument);
8011b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org        ast_context()->ReturnInstruction(result, expr->id());
8012b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org        return true;
8013b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      }
8014b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org      break;
80151f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org    case kMathExp:
80161f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org      if (!FLAG_fast_math) break;
80171f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org      // Fall through if FLAG_fast_math.
8018a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case kMathRound:
8019a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case kMathFloor:
8020a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case kMathAbs:
8021a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    case kMathSqrt:
80225f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    case kMathLog:
8023f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    case kMathClz32:
8024a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      if (argument_count == 2) {
8025a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        HValue* argument = Pop();
8026a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        Drop(2);  // Receiver and function.
8027db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org        HInstruction* op = NewUncasted<HUnaryMathOperation>(argument, id);
80285f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org        ast_context()->ReturnInstruction(op, expr->id());
80295f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org        return true;
80305f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org      }
80315f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org      break;
80325f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    case kMathPow:
8033a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      if (argument_count == 3) {
80345f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org        HValue* right = Pop();
80355f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org        HValue* left = Pop();
8036a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        Drop(2);  // Receiver and function.
80375f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org        HInstruction* result = NULL;
80385f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org        // Use sqrt() if exponent is 0.5 or -0.5.
80395f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org        if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) {
80405f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org          double exponent = HConstant::cast(right)->DoubleValue();
80415f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org          if (exponent == 0.5) {
8042db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org            result = NewUncasted<HUnaryMathOperation>(left, kMathPowHalf);
80435f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org          } else if (exponent == -0.5) {
8044b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org            HValue* one = graph()->GetConstant1();
8045db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org            HInstruction* sqrt = AddUncasted<HUnaryMathOperation>(
8046db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org                left, kMathPowHalf);
80475f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org            // MathPowHalf doesn't have side effects so there's no need for
80485f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org            // an environment simulation here.
80492e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org            ASSERT(!sqrt->HasObservableSideEffects());
8050db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org            result = NewUncasted<HDiv>(one, sqrt);
80515f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org          } else if (exponent == 2.0) {
8052db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org            result = NewUncasted<HMul>(left, left);
80535f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org          }
80545f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org        }
80555f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
80560a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        if (result == NULL) {
8057db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org          result = NewUncasted<HPower>(left, right);
80580a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org        }
80595f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org        ast_context()->ReturnInstruction(result, expr->id());
8060a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        return true;
8061a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
8062a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      break;
8063f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    case kMathMax:
8064f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    case kMathMin:
8065a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      if (argument_count == 3) {
8066f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        HValue* right = Pop();
8067f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        HValue* left = Pop();
8068a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        Drop(2);  // Receiver and function.
8069471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org        HMathMinMax::Operation op = (id == kMathMin) ? HMathMinMax::kMathMin
8070471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                                                     : HMathMinMax::kMathMax;
8071db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org        HInstruction* result = NewUncasted<HMathMinMax>(left, right, op);
8072471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org        ast_context()->ReturnInstruction(result, expr->id());
8073f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        return true;
8074f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      }
8075f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      break;
8076ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    case kMathImul:
8077a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      if (argument_count == 3) {
8078ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org        HValue* right = Pop();
8079ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org        HValue* left = Pop();
8080a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        Drop(2);  // Receiver and function.
8081db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org        HInstruction* result = HMul::NewImul(zone(), context(), left, right);
8082ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org        ast_context()->ReturnInstruction(result, expr->id());
8083ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org        return true;
8084ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      }
8085ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      break;
8086af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case kArrayPop: {
8087a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      if (receiver_map.is_null()) return false;
8088af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false;
8089af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      ElementsKind elements_kind = receiver_map->elements_kind();
8090af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      if (!IsFastElementsKind(elements_kind)) return false;
80918496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      if (receiver_map->is_observed()) return false;
80928496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      ASSERT(receiver_map->is_extensible());
8093af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
80943ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org      Drop(expr->arguments()->length());
8095af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      HValue* result;
8096af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      HValue* reduced_length;
8097af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      HValue* receiver = Pop();
809809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
809909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      HValue* checked_object = AddCheckMap(receiver, receiver_map);
810009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      HValue* length = Add<HLoadNamedField>(
810109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org          checked_object, static_cast<HValue*>(NULL),
810209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org          HObjectAccess::ForArrayLength(elements_kind));
810309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
8104a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      Drop(1);  // Function.
8105a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org
8106af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      { NoObservableSideEffectsScope scope(this);
810709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org        IfBuilder length_checker(this);
810809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
810909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org        HValue* bounds_check = length_checker.If<HCompareNumericAndBranch>(
811009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org            length, graph()->GetConstant0(), Token::EQ);
811109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org        length_checker.Then();
811209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
811309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org        if (!ast_context()->IsEffect()) Push(graph()->GetConstantUndefined());
811409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
811509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org        length_checker.Else();
8116af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org        HValue* elements = AddLoadElements(checked_object);
8117af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org        // Ensure that we aren't popping from a copy-on-write array.
8118af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org        if (IsFastSmiOrObjectElementsKind(elements_kind)) {
811909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org          elements = BuildCopyElementsOnWrite(checked_object, elements,
812009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org                                              elements_kind, length);
8121af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org        }
8122af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org        reduced_length = AddUncasted<HSub>(length, graph()->GetConstant1());
8123af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org        result = AddElementAccess(elements, reduced_length, NULL,
8124f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                  bounds_check, elements_kind, LOAD);
8125af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org        Factory* factory = isolate()->factory();
8126af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org        double nan_double = FixedDoubleArray::hole_nan_as_double();
8127af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org        HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind)
8128af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org            ? Add<HConstant>(factory->the_hole_value())
8129af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org            : Add<HConstant>(nan_double);
8130af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org        if (IsFastSmiOrObjectElementsKind(elements_kind)) {
8131af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org          elements_kind = FAST_HOLEY_ELEMENTS;
8132af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org        }
8133af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org        AddElementAccess(
8134f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org            elements, reduced_length, hole, bounds_check, elements_kind, STORE);
813509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org        Add<HStoreNamedField>(
813609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org            checked_object, HObjectAccess::ForArrayLength(elements_kind),
813709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org            reduced_length, STORE_TO_INITIALIZED_ENTRY);
813809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
813909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org        if (!ast_context()->IsEffect()) Push(result);
814009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
814109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org        length_checker.End();
8142af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      }
814309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top();
8144af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
8145af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      if (!ast_context()->IsEffect()) Drop(1);
814609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
8147af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      ast_context()->ReturnValue(result);
8148af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      return true;
8149af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    }
8150af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    case kArrayPush: {
8151a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      if (receiver_map.is_null()) return false;
8152af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false;
8153af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      ElementsKind elements_kind = receiver_map->elements_kind();
8154af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      if (!IsFastElementsKind(elements_kind)) return false;
81558496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      if (receiver_map->is_observed()) return false;
8156fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      if (JSArray::IsReadOnlyLengthDescriptor(receiver_map)) return false;
81578496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      ASSERT(receiver_map->is_extensible());
8158af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
8159202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      // If there may be elements accessors in the prototype chain, the fast
8160202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      // inlined version can't be used.
8161202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false;
8162202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      // If there currently can be no elements accessors on the prototype chain,
8163202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      // it doesn't mean that there won't be any later. Install a full prototype
8164202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      // chain check to trap element accessors being installed on the prototype
8165202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      // chain, which would cause elements to go to dictionary mode and result
8166202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      // in a map change.
8167202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype()));
8168202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      BuildCheckPrototypeMaps(prototype, Handle<JSObject>());
8169202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org
81703ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org      const int argc = expr->arguments()->length();
81718496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      if (argc != 1) return false;
8172af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
81738496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      HValue* value_to_push = Pop();
81748496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      HValue* array = Pop();
8175b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org      Drop(1);  // Drop function.
8176af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
8177a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org      HInstruction* new_size = NULL;
8178a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org      HValue* length = NULL;
8179af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
81808496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      {
81818496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        NoObservableSideEffectsScope scope(this);
81828496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
8183a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org        length = Add<HLoadNamedField>(array, static_cast<HValue*>(NULL),
8184a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org          HObjectAccess::ForArrayLength(elements_kind));
8185a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org
8186a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org        new_size = AddUncasted<HAdd>(length, graph()->GetConstant1());
8187a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org
81888496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        bool is_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
81898496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        BuildUncheckedMonomorphicElementAccess(array, length,
81908496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org                                               value_to_push, is_array,
81918496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org                                               elements_kind, STORE,
81928496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org                                               NEVER_RETURN_HOLE,
81938496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org                                               STORE_AND_GROW_NO_TRANSITION);
8194b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org
8195b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org        if (!ast_context()->IsEffect()) Push(new_size);
8196a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org        Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
8197b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org        if (!ast_context()->IsEffect()) Drop(1);
81988496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      }
8199af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
8200a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org      ast_context()->ReturnValue(new_size);
8201af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org      return true;
8202af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    }
82033c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    case kArrayShift: {
82043c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      if (receiver_map.is_null()) return false;
82053c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false;
82063c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      ElementsKind kind = receiver_map->elements_kind();
82073c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      if (!IsFastElementsKind(kind)) return false;
82083c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      if (receiver_map->is_observed()) return false;
82093c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      ASSERT(receiver_map->is_extensible());
82103c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org
82113c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      // If there may be elements accessors in the prototype chain, the fast
82123c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      // inlined version can't be used.
82133c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false;
82143c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org
82153c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      // If there currently can be no elements accessors on the prototype chain,
82163c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      // it doesn't mean that there won't be any later. Install a full prototype
82173c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      // chain check to trap element accessors being installed on the prototype
82183c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      // chain, which would cause elements to go to dictionary mode and result
82193c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      // in a map change.
82203c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      BuildCheckPrototypeMaps(
82213c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org          handle(JSObject::cast(receiver_map->prototype()), isolate()),
82223c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org          Handle<JSObject>::null());
82233c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org
82248d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      // Threshold for fast inlined Array.shift().
82258d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      HConstant* inline_threshold = Add<HConstant>(static_cast<int32_t>(16));
82268d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
82273ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org      Drop(expr->arguments()->length());
82283c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      HValue* receiver = Pop();
82298d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      HValue* function = Pop();
82308d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      HValue* result;
82318d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
82328d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      {
82338d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org        NoObservableSideEffectsScope scope(this);
82348d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
82358d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org        HValue* length = Add<HLoadNamedField>(
82368d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            receiver, static_cast<HValue*>(NULL),
82378d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            HObjectAccess::ForArrayLength(kind));
82388d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
82398d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org        IfBuilder if_lengthiszero(this);
82408d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org        HValue* lengthiszero = if_lengthiszero.If<HCompareNumericAndBranch>(
82418d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            length, graph()->GetConstant0(), Token::EQ);
82428d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org        if_lengthiszero.Then();
82438d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org        {
82448d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org          if (!ast_context()->IsEffect()) Push(graph()->GetConstantUndefined());
82458d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org        }
82468d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org        if_lengthiszero.Else();
82478d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org        {
82488d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org          HValue* elements = AddLoadElements(receiver);
82498d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
82508d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org          // Check if we can use the fast inlined Array.shift().
82518d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org          IfBuilder if_inline(this);
82528d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org          if_inline.If<HCompareNumericAndBranch>(
82538d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org              length, inline_threshold, Token::LTE);
82548d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org          if (IsFastSmiOrObjectElementsKind(kind)) {
82558d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            // We cannot handle copy-on-write backing stores here.
82568d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            if_inline.AndIf<HCompareMap>(
82578d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                elements, isolate()->factory()->fixed_array_map());
82588d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org          }
82598d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org          if_inline.Then();
82608d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org          {
82618d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            // Remember the result.
82628d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            if (!ast_context()->IsEffect()) {
82638d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org              Push(AddElementAccess(elements, graph()->GetConstant0(), NULL,
82648d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                                    lengthiszero, kind, LOAD));
82658d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            }
82668d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
82678d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            // Compute the new length.
82688d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            HValue* new_length = AddUncasted<HSub>(
82698d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                length, graph()->GetConstant1());
82708d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            new_length->ClearFlag(HValue::kCanOverflow);
82713c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org
82728d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            // Copy the remaining elements.
82738d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement);
82748d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            {
82758d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org              HValue* new_key = loop.BeginBody(
82768d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                  graph()->GetConstant0(), new_length, Token::LT);
82778d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org              HValue* key = AddUncasted<HAdd>(new_key, graph()->GetConstant1());
82788d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org              key->ClearFlag(HValue::kCanOverflow);
82798d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org              HValue* element = AddUncasted<HLoadKeyed>(
82808d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                  elements, key, lengthiszero, kind, ALLOW_RETURN_HOLE);
82818d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org              HStoreKeyed* store = Add<HStoreKeyed>(
82828d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                  elements, new_key, element, kind);
82838d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org              store->SetFlag(HValue::kAllowUndefinedAsNaN);
82848d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            }
82858d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            loop.EndBody();
82868d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
82878d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            // Put a hole at the end.
82888d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            HValue* hole = IsFastSmiOrObjectElementsKind(kind)
82898d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                ? Add<HConstant>(isolate()->factory()->the_hole_value())
82908d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                : Add<HConstant>(FixedDoubleArray::hole_nan_as_double());
82918d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            if (IsFastSmiOrObjectElementsKind(kind)) kind = FAST_HOLEY_ELEMENTS;
82928d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            Add<HStoreKeyed>(
82938d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                elements, new_length, hole, kind, INITIALIZING_STORE);
82948d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
82958d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            // Remember new length.
82968d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            Add<HStoreNamedField>(
82978d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                receiver, HObjectAccess::ForArrayLength(kind),
82988d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                new_length, STORE_TO_INITIALIZED_ENTRY);
82998d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org          }
83008d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org          if_inline.Else();
83018d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org          {
83028d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            Add<HPushArguments>(receiver);
83038d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            result = Add<HCallJSFunction>(function, 1, true);
83048d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org            if (!ast_context()->IsEffect()) Push(result);
83058d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org          }
83068d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org          if_inline.End();
83078d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org        }
83088d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org        if_lengthiszero.End();
83098d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      }
83108d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top();
83118d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
83128d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      if (!ast_context()->IsEffect()) Drop(1);
83138d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      ast_context()->ReturnValue(result);
83143c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      return true;
83153c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    }
8316196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    case kArrayIndexOf:
8317196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    case kArrayLastIndexOf: {
8318196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      if (receiver_map.is_null()) return false;
8319196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false;
8320196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      ElementsKind kind = receiver_map->elements_kind();
8321196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      if (!IsFastElementsKind(kind)) return false;
8322196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      if (receiver_map->is_observed()) return false;
8323196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      if (argument_count != 2) return false;
8324196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      ASSERT(receiver_map->is_extensible());
8325196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
8326196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      // If there may be elements accessors in the prototype chain, the fast
8327196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      // inlined version can't be used.
8328196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false;
8329196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
8330196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      // If there currently can be no elements accessors on the prototype chain,
8331196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      // it doesn't mean that there won't be any later. Install a full prototype
8332196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      // chain check to trap element accessors being installed on the prototype
8333196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      // chain, which would cause elements to go to dictionary mode and result
8334196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      // in a map change.
8335196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      BuildCheckPrototypeMaps(
8336196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          handle(JSObject::cast(receiver_map->prototype()), isolate()),
8337196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          Handle<JSObject>::null());
8338196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
8339196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      HValue* search_element = Pop();
8340196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      HValue* receiver = Pop();
8341196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      Drop(1);  // Drop function.
8342196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
8343196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      ArrayIndexOfMode mode = (id == kArrayIndexOf)
8344196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          ? kFirstIndexOf : kLastIndexOf;
8345196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      HValue* index = BuildArrayIndexOf(receiver, search_element, kind, mode);
8346196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
8347196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      if (!ast_context()->IsEffect()) Push(index);
8348196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
8349196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      if (!ast_context()->IsEffect()) Drop(1);
8350196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      ast_context()->ReturnValue(index);
8351196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      return true;
8352196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    }
8353a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    default:
83545f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org      // Not yet supported for inlining.
8355a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      break;
8356a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
8357a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return false;
8358a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
8359a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8360a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
836157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.orgbool HOptimizedGraphBuilder::TryInlineApiFunctionCall(Call* expr,
8362a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org                                                      HValue* receiver) {
83638297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  Handle<JSFunction> function = expr->target();
83648297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  int argc = expr->arguments()->length();
83658297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  SmallMapList receiver_maps;
83668297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  return TryInlineApiCall(function,
83678297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                          receiver,
83688297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                          &receiver_maps,
83698297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                          argc,
83708297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                          expr->id(),
83718297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                          kCallApiFunction);
837257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org}
837357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
837457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
83758297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.orgbool HOptimizedGraphBuilder::TryInlineApiMethodCall(
83768297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    Call* expr,
83778297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    HValue* receiver,
83788297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    SmallMapList* receiver_maps) {
83798297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  Handle<JSFunction> function = expr->target();
83808297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  int argc = expr->arguments()->length();
83818297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  return TryInlineApiCall(function,
83828297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                          receiver,
83838297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                          receiver_maps,
83848297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                          argc,
83858297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                          expr->id(),
83868297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                          kCallApiMethod);
83878297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org}
83888297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org
83898297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org
83908297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.orgbool HOptimizedGraphBuilder::TryInlineApiGetter(Handle<JSFunction> function,
83918297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                                Handle<Map> receiver_map,
83928297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                                BailoutId ast_id) {
83938297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  SmallMapList receiver_maps(1, zone());
83948297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  receiver_maps.Add(receiver_map, zone());
83958297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  return TryInlineApiCall(function,
83968297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                          NULL,  // Receiver is on expression stack.
83978297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                          &receiver_maps,
83988297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                          0,
83998297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                          ast_id,
84008297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                          kCallApiGetter);
84018297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org}
84028297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org
84038297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org
840425530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.orgbool HOptimizedGraphBuilder::TryInlineApiSetter(Handle<JSFunction> function,
840525530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org                                                Handle<Map> receiver_map,
840625530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org                                                BailoutId ast_id) {
840725530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org  SmallMapList receiver_maps(1, zone());
840825530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org  receiver_maps.Add(receiver_map, zone());
840925530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org  return TryInlineApiCall(function,
841025530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org                          NULL,  // Receiver is on expression stack.
841125530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org                          &receiver_maps,
841225530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org                          1,
841325530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org                          ast_id,
841425530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org                          kCallApiSetter);
841525530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org}
841625530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org
841725530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org
84188297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.orgbool HOptimizedGraphBuilder::TryInlineApiCall(Handle<JSFunction> function,
84198297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                               HValue* receiver,
84208297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                               SmallMapList* receiver_maps,
84218297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                               int argc,
84228297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                               BailoutId ast_id,
84238297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org                                               ApiCallType call_type) {
84248297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  CallOptimization optimization(function);
842557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  if (!optimization.is_simple_api_call()) return false;
842657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  Handle<Map> holder_map;
84278297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  if (call_type == kCallApiFunction) {
842857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    // Cannot embed a direct reference to the global proxy map
842957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    // as it maybe dropped on deserialization.
8430fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    CHECK(!isolate()->serializer_enabled());
84318297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    ASSERT_EQ(0, receiver_maps->length());
84328297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    receiver_maps->Add(handle(
84338297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org        function->context()->global_object()->global_receiver()->map()),
84348297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org        zone());
843557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  }
843657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  CallOptimization::HolderLookup holder_lookup =
843757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      CallOptimization::kHolderNotFound;
843857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType(
84398297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      receiver_maps->first(), &holder_lookup);
844057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  if (holder_lookup == CallOptimization::kHolderNotFound) return false;
844157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
844257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  if (FLAG_trace_inlining) {
844357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    PrintF("Inlining api function ");
84448297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    function->ShortPrint();
844557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    PrintF("\n");
844657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  }
844757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
84488297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  bool drop_extra = false;
8449f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  bool is_store = false;
84508297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  switch (call_type) {
84518297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    case kCallApiFunction:
84528297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    case kCallApiMethod:
84538297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      // Need to check that none of the receiver maps could have changed.
8454052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org      Add<HCheckMaps>(receiver, receiver_maps);
84558297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      // Need to ensure the chain between receiver and api_holder is intact.
84568297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      if (holder_lookup == CallOptimization::kHolderFound) {
84578297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org        AddCheckPrototypeMaps(api_holder, receiver_maps->first());
84588297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      } else {
84598297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org        ASSERT_EQ(holder_lookup, CallOptimization::kHolderIsReceiver);
84608297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      }
84618297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      // Includes receiver.
84628297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      PushArgumentsFromEnvironment(argc + 1);
84638297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      // Drop function after call.
84648297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      drop_extra = true;
84658297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      break;
84668297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    case kCallApiGetter:
84678297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      // Receiver and prototype chain cannot have changed.
84688297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      ASSERT_EQ(0, argc);
84698297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      ASSERT_EQ(NULL, receiver);
84708297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      // Receiver is on expression stack.
84718297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      receiver = Pop();
84728d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      Add<HPushArguments>(receiver);
84738297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      break;
847425530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org    case kCallApiSetter:
847525530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org      {
8476f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        is_store = true;
847725530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org        // Receiver and prototype chain cannot have changed.
847825530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org        ASSERT_EQ(1, argc);
847925530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org        ASSERT_EQ(NULL, receiver);
848025530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org        // Receiver and value are on expression stack.
848125530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org        HValue* value = Pop();
848225530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org        receiver = Pop();
84838d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org        Add<HPushArguments>(receiver, value);
848425530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org        break;
848525530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org     }
848657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  }
848757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
848857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  HValue* holder = NULL;
848957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  switch (holder_lookup) {
849057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    case CallOptimization::kHolderFound:
849157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      holder = Add<HConstant>(api_holder);
849257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      break;
849357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    case CallOptimization::kHolderIsReceiver:
8494a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      holder = receiver;
849557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      break;
849657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    case CallOptimization::kHolderNotFound:
849757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      UNREACHABLE();
849857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      break;
849957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  }
850057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
850157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  Handle<Object> call_data_obj(api_call_info->data(), isolate());
850257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  bool call_data_is_undefined = call_data_obj->IsUndefined();
850357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  HValue* call_data = Add<HConstant>(call_data_obj);
850457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  ApiFunction fun(v8::ToCData<Address>(api_call_info->callback()));
850557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  ExternalReference ref = ExternalReference(&fun,
850657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org                                            ExternalReference::DIRECT_API_CALL,
850757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org                                            isolate());
850857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  HValue* api_function_address = Add<HConstant>(ExternalReference(ref));
850957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
851057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  HValue* op_vals[] = {
85118297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    Add<HConstant>(function),
851257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    call_data,
851357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    holder,
851457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    api_function_address,
851557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    context()
851657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  };
851757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
851857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  CallInterfaceDescriptor* descriptor =
851957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      isolate()->call_descriptor(Isolate::ApiFunctionCall);
852057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
8521f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  CallApiFunctionStub stub(isolate(), is_store, call_data_is_undefined, argc);
8522f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  Handle<Code> code = stub.GetCode();
852357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  HConstant* code_value = Add<HConstant>(code);
852457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
852557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  ASSERT((sizeof(op_vals) / kPointerSize) ==
852657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org         descriptor->environment_length());
852757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
852857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  HInstruction* call = New<HCallWithDescriptor>(
852957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      code_value, argc + 1, descriptor,
853057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org      Vector<HValue*>(op_vals, descriptor->environment_length()));
853157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
85328297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  if (drop_extra) Drop(1);  // Drop function.
85338297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  ast_context()->ReturnInstruction(call, ast_id);
853457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  return true;
853557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org}
853657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
853757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
85383ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgbool HOptimizedGraphBuilder::TryCallApply(Call* expr) {
8539a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  ASSERT(expr->expression()->IsProperty());
8540a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8541a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  if (!expr->IsMonomorphic()) {
85424acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    return false;
85434acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  }
85444acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  Handle<Map> function_map = expr->GetReceiverTypes()->first();
85454acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  if (function_map->instance_type() != JS_FUNCTION_TYPE ||
85463ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org      !expr->target()->shared()->HasBuiltinFunctionId() ||
85473ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org      expr->target()->shared()->builtin_function_id() != kFunctionApply) {
85484acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org    return false;
85494acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  }
8550a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
85513ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  if (current_info()->scope()->arguments() == NULL) return false;
855270ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org
85533ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  ZoneList<Expression*>* args = expr->arguments();
85543ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  if (args->length() != 2) return false;
8555a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
85563ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  VariableProxy* arg_two = args->at(1)->AsVariableProxy();
85573ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false;
85583ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  HValue* arg_two_value = LookupAndMakeLive(arg_two->var());
85593ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false;
8560a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
85613ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  // Found pattern f.apply(receiver, arguments).
85623ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  CHECK_ALIVE_OR_RETURN(VisitForValue(args->at(0)), true);
8563a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  HValue* receiver = Pop();  // receiver
8564a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  HValue* function = Pop();  // f
8565a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  Drop(1);  // apply
85664ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org
8567dc9b14d0e5f039213f6644c9ec2ffab31ad27a5cjarin@chromium.org  HValue* checked_function = AddCheckMap(function, function_map);
8568dc9b14d0e5f039213f6644c9ec2ffab31ad27a5cjarin@chromium.org
8569154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  if (function_state()->outer() == NULL) {
85701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    HInstruction* elements = Add<HArgumentsElements>(false);
85711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    HInstruction* length = Add<HArgumentsLength>(elements);
8572dc9b14d0e5f039213f6644c9ec2ffab31ad27a5cjarin@chromium.org    HValue* wrapped_receiver = BuildWrapReceiver(receiver, checked_function);
8573db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org    HInstruction* result = New<HApplyArguments>(function,
8574db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org                                                wrapped_receiver,
8575db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org                                                length,
8576db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org                                                elements);
8577154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    ast_context()->ReturnInstruction(result, expr->id());
85783ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org    return true;
8579154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  } else {
8580154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org    // We are inside inlined function and we know exactly what is inside
858139110192b21bd92be3d617690fc33b4e9551b95dyangguo@chromium.org    // arguments object. But we need to be able to materialize at deopt.
8582c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    ASSERT_EQ(environment()->arguments_environment()->parameter_count(),
8583b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org              function_state()->entry()->arguments_object()->arguments_count());
8584b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    HArgumentsObject* args = function_state()->entry()->arguments_object();
8585b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    const ZoneList<HValue*>* arguments_values = args->arguments_values();
8586c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    int arguments_count = arguments_values->length();
8587a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    Push(function);
8588dc9b14d0e5f039213f6644c9ec2ffab31ad27a5cjarin@chromium.org    Push(BuildWrapReceiver(receiver, checked_function));
8589c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    for (int i = 1; i < arguments_count; i++) {
8590c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org      Push(arguments_values->at(i));
85916ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org    }
85926ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org
85933ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org    Handle<JSFunction> known_function;
85943ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org    if (function->IsConstant() &&
85953ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org        HConstant::cast(function)->handle(isolate())->IsJSFunction()) {
85963ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org      known_function = Handle<JSFunction>::cast(
85973ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org          HConstant::cast(function)->handle(isolate()));
85983ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org      int args_count = arguments_count - 1;  // Excluding receiver.
85993ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org      if (TryInlineApply(known_function, expr, args_count)) return true;
86003ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org    }
86016ba1fd0b7bebfbcabc4ad3cdaf9b84aad9651962ulan@chromium.org
86023ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org    PushArgumentsFromEnvironment(arguments_count);
86033ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org    HInvokeFunction* call = New<HInvokeFunction>(
86043ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org        function, known_function, arguments_count);
86053ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org    Drop(1);  // Function.
86063ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org    ast_context()->ReturnInstruction(call, expr->id());
86073ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org    return true;
8608154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  }
8609a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
8610a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8611a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8612e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.orgHValue* HOptimizedGraphBuilder::ImplicitReceiverFor(HValue* function,
8613e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org                                                    Handle<JSFunction> target) {
8614e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  SharedFunctionInfo* shared = target->shared();
8615486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  if (shared->strict_mode() == SLOPPY && !shared->native()) {
861657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    // Cannot embed a direct reference to the global proxy
861757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    // as is it dropped on deserialization.
8618fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    CHECK(!isolate()->serializer_enabled());
861957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    Handle<JSObject> global_receiver(
862057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org        target->context()->global_object()->global_receiver());
862157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org    return Add<HConstant>(global_receiver);
8622e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  }
8623e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  return graph()->GetConstantUndefined();
86249ed27460593e67bc55b9feb15ca7c301e9f804b0rossberg@chromium.org}
86259ed27460593e67bc55b9feb15ca7c301e9f804b0rossberg@chromium.org
86269ed27460593e67bc55b9feb15ca7c301e9f804b0rossberg@chromium.org
86277e6132b924829c353864933f29124419916db550machenbach@chromium.orgvoid HOptimizedGraphBuilder::BuildArrayCall(Expression* expression,
86287e6132b924829c353864933f29124419916db550machenbach@chromium.org                                            int arguments_count,
86297e6132b924829c353864933f29124419916db550machenbach@chromium.org                                            HValue* function,
86307e6132b924829c353864933f29124419916db550machenbach@chromium.org                                            Handle<AllocationSite> site) {
86317e6132b924829c353864933f29124419916db550machenbach@chromium.org  Add<HCheckValue>(function, array_function());
86327e6132b924829c353864933f29124419916db550machenbach@chromium.org
86337e6132b924829c353864933f29124419916db550machenbach@chromium.org  if (IsCallArrayInlineable(arguments_count, site)) {
86347e6132b924829c353864933f29124419916db550machenbach@chromium.org    BuildInlinedCallArray(expression, arguments_count, site);
86357e6132b924829c353864933f29124419916db550machenbach@chromium.org    return;
86367e6132b924829c353864933f29124419916db550machenbach@chromium.org  }
86377e6132b924829c353864933f29124419916db550machenbach@chromium.org
86387e6132b924829c353864933f29124419916db550machenbach@chromium.org  HInstruction* call = PreProcessCall(New<HCallNewArray>(
86397e6132b924829c353864933f29124419916db550machenbach@chromium.org      function, arguments_count + 1, site->GetElementsKind()));
86407e6132b924829c353864933f29124419916db550machenbach@chromium.org  if (expression->IsCall()) {
86417e6132b924829c353864933f29124419916db550machenbach@chromium.org    Drop(1);
86427e6132b924829c353864933f29124419916db550machenbach@chromium.org  }
86437e6132b924829c353864933f29124419916db550machenbach@chromium.org  ast_context()->ReturnInstruction(call, expression->id());
86447e6132b924829c353864933f29124419916db550machenbach@chromium.org}
86457e6132b924829c353864933f29124419916db550machenbach@chromium.org
86467e6132b924829c353864933f29124419916db550machenbach@chromium.org
8647196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgHValue* HOptimizedGraphBuilder::BuildArrayIndexOf(HValue* receiver,
8648196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                                                  HValue* search_element,
8649196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                                                  ElementsKind kind,
8650196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                                                  ArrayIndexOfMode mode) {
8651196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  ASSERT(IsFastElementsKind(kind));
8652196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
8653196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  NoObservableSideEffectsScope no_effects(this);
8654196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
8655196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  HValue* elements = AddLoadElements(receiver);
8656196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  HValue* length = AddLoadArrayLength(receiver, kind);
8657196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
8658196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  HValue* initial;
8659196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  HValue* terminating;
8660196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  Token::Value token;
8661196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  LoopBuilder::Direction direction;
8662196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (mode == kFirstIndexOf) {
8663196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    initial = graph()->GetConstant0();
8664196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    terminating = length;
8665196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    token = Token::LT;
8666196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    direction = LoopBuilder::kPostIncrement;
8667196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  } else {
8668196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    ASSERT_EQ(kLastIndexOf, mode);
8669196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    initial = length;
8670196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    terminating = graph()->GetConstant0();
867138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org    token = Token::GT;
8672196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    direction = LoopBuilder::kPreDecrement;
8673196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  }
8674196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
8675196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  Push(graph()->GetConstantMinus1());
8676196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (IsFastDoubleElementsKind(kind) || IsFastSmiElementsKind(kind)) {
8677196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    LoopBuilder loop(this, context(), direction);
8678196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    {
8679196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      HValue* index = loop.BeginBody(initial, terminating, token);
8680196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      HValue* element = AddUncasted<HLoadKeyed>(
8681196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          elements, index, static_cast<HValue*>(NULL),
8682196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          kind, ALLOW_RETURN_HOLE);
8683196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      IfBuilder if_issame(this);
8684196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      if (IsFastDoubleElementsKind(kind)) {
8685196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        if_issame.If<HCompareNumericAndBranch>(
8686196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org            element, search_element, Token::EQ_STRICT);
8687196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      } else {
8688196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        if_issame.If<HCompareObjectEqAndBranch>(element, search_element);
8689196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      }
8690196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      if_issame.Then();
8691196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      {
8692196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        Drop(1);
8693196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        Push(index);
8694196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        loop.Break();
8695196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      }
8696196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      if_issame.End();
8697196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    }
8698196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    loop.EndBody();
8699196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  } else {
8700196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    IfBuilder if_isstring(this);
8701196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    if_isstring.If<HIsStringAndBranch>(search_element);
8702196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    if_isstring.Then();
8703196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    {
8704196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      LoopBuilder loop(this, context(), direction);
8705196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      {
8706196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        HValue* index = loop.BeginBody(initial, terminating, token);
8707196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        HValue* element = AddUncasted<HLoadKeyed>(
8708196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org            elements, index, static_cast<HValue*>(NULL),
8709196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org            kind, ALLOW_RETURN_HOLE);
8710196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        IfBuilder if_issame(this);
8711196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        if_issame.If<HIsStringAndBranch>(element);
8712196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        if_issame.AndIf<HStringCompareAndBranch>(
8713196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org            element, search_element, Token::EQ_STRICT);
8714196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        if_issame.Then();
8715196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        {
8716196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          Drop(1);
8717196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          Push(index);
8718196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          loop.Break();
8719196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        }
8720196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        if_issame.End();
8721196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      }
8722196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      loop.EndBody();
8723196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    }
8724196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    if_isstring.Else();
8725196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    {
8726e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      IfBuilder if_isnumber(this);
8727e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      if_isnumber.If<HIsSmiAndBranch>(search_element);
8728e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      if_isnumber.OrIf<HCompareMap>(
8729196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          search_element, isolate()->factory()->heap_number_map());
8730e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      if_isnumber.Then();
8731196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      {
8732e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org        HValue* search_number =
8733e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org            AddUncasted<HForceRepresentation>(search_element,
8734e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                                              Representation::Double());
8735196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        LoopBuilder loop(this, context(), direction);
8736196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        {
8737196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          HValue* index = loop.BeginBody(initial, terminating, token);
8738196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          HValue* element = AddUncasted<HLoadKeyed>(
8739196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org              elements, index, static_cast<HValue*>(NULL),
8740196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org              kind, ALLOW_RETURN_HOLE);
8741e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org
8742e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org          IfBuilder if_element_isnumber(this);
8743e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org          if_element_isnumber.If<HIsSmiAndBranch>(element);
8744e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org          if_element_isnumber.OrIf<HCompareMap>(
8745196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org              element, isolate()->factory()->heap_number_map());
8746e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org          if_element_isnumber.Then();
8747196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          {
8748e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org            HValue* number =
8749e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                AddUncasted<HForceRepresentation>(element,
8750e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                                                  Representation::Double());
8751e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org            IfBuilder if_issame(this);
8752e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org            if_issame.If<HCompareNumericAndBranch>(
8753e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                number, search_number, Token::EQ_STRICT);
8754e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org            if_issame.Then();
8755e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org            {
8756e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org              Drop(1);
8757e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org              Push(index);
8758e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org              loop.Break();
8759e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org            }
8760e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org            if_issame.End();
8761196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          }
8762e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org          if_element_isnumber.End();
8763196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        }
8764196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        loop.EndBody();
8765196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      }
8766e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      if_isnumber.Else();
8767196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      {
8768196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        LoopBuilder loop(this, context(), direction);
8769196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        {
8770196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          HValue* index = loop.BeginBody(initial, terminating, token);
8771196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          HValue* element = AddUncasted<HLoadKeyed>(
8772196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org              elements, index, static_cast<HValue*>(NULL),
8773196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org              kind, ALLOW_RETURN_HOLE);
8774196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          IfBuilder if_issame(this);
8775196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          if_issame.If<HCompareObjectEqAndBranch>(
8776196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org              element, search_element);
8777196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          if_issame.Then();
8778196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          {
8779196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org            Drop(1);
8780196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org            Push(index);
8781196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org            loop.Break();
8782196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          }
8783196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          if_issame.End();
8784196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        }
8785196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org        loop.EndBody();
8786196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      }
8787e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      if_isnumber.End();
8788196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    }
8789196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org    if_isstring.End();
8790196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  }
8791196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
8792196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  return Pop();
8793196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org}
8794196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
8795196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
87967e6132b924829c353864933f29124419916db550machenbach@chromium.orgbool HOptimizedGraphBuilder::TryHandleArrayCall(Call* expr, HValue* function) {
87977e6132b924829c353864933f29124419916db550machenbach@chromium.org  if (!array_function().is_identical_to(expr->target())) {
87987e6132b924829c353864933f29124419916db550machenbach@chromium.org    return false;
87997e6132b924829c353864933f29124419916db550machenbach@chromium.org  }
88007e6132b924829c353864933f29124419916db550machenbach@chromium.org
88017e6132b924829c353864933f29124419916db550machenbach@chromium.org  Handle<AllocationSite> site = expr->allocation_site();
88027e6132b924829c353864933f29124419916db550machenbach@chromium.org  if (site.is_null()) return false;
88037e6132b924829c353864933f29124419916db550machenbach@chromium.org
88047e6132b924829c353864933f29124419916db550machenbach@chromium.org  BuildArrayCall(expr,
88057e6132b924829c353864933f29124419916db550machenbach@chromium.org                 expr->arguments()->length(),
88067e6132b924829c353864933f29124419916db550machenbach@chromium.org                 function,
88077e6132b924829c353864933f29124419916db550machenbach@chromium.org                 site);
88087e6132b924829c353864933f29124419916db550machenbach@chromium.org  return true;
88097e6132b924829c353864933f29124419916db550machenbach@chromium.org}
88107e6132b924829c353864933f29124419916db550machenbach@chromium.org
88117e6132b924829c353864933f29124419916db550machenbach@chromium.org
88127e6132b924829c353864933f29124419916db550machenbach@chromium.orgbool HOptimizedGraphBuilder::TryHandleArrayCallNew(CallNew* expr,
88137e6132b924829c353864933f29124419916db550machenbach@chromium.org                                                   HValue* function) {
88147e6132b924829c353864933f29124419916db550machenbach@chromium.org  if (!array_function().is_identical_to(expr->target())) {
88157e6132b924829c353864933f29124419916db550machenbach@chromium.org    return false;
88167e6132b924829c353864933f29124419916db550machenbach@chromium.org  }
88177e6132b924829c353864933f29124419916db550machenbach@chromium.org
88187e6132b924829c353864933f29124419916db550machenbach@chromium.org  BuildArrayCall(expr,
88197e6132b924829c353864933f29124419916db550machenbach@chromium.org                 expr->arguments()->length(),
88207e6132b924829c353864933f29124419916db550machenbach@chromium.org                 function,
88217e6132b924829c353864933f29124419916db550machenbach@chromium.org                 expr->allocation_site());
88227e6132b924829c353864933f29124419916db550machenbach@chromium.org  return true;
88237e6132b924829c353864933f29124419916db550machenbach@chromium.org}
88247e6132b924829c353864933f29124419916db550machenbach@chromium.org
88257e6132b924829c353864933f29124419916db550machenbach@chromium.org
8826a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitCall(Call* expr) {
8827160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
8828160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
8829160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
8830a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Expression* callee = expr->expression();
8831a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int argument_count = expr->arguments()->length() + 1;  // Plus receiver.
88323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  HInstruction* call = NULL;
8833a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8834a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Property* prop = callee->AsProperty();
8835a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (prop != NULL) {
8836a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    CHECK_ALIVE(VisitForValue(prop->obj()));
8837a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    HValue* receiver = Top();
8838ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
8839a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    SmallMapList* types;
88400a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    ComputeReceiverTypes(expr, receiver, &types, zone());
8841ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
8842a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    if (prop->key()->IsPropertyName() && types->length() > 0) {
8843a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
88440a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      PropertyAccessInfo info(this, LOAD, ToType(types->first()), name);
88450a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      if (!info.CanAccessAsMonomorphic(types)) {
8846a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        HandlePolymorphicCallNamed(expr, receiver, types, name);
8847a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        return;
8848ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      }
8849a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
8850a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8851a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    HValue* key = NULL;
8852a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    if (!prop->key()->IsPropertyName()) {
8853a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      CHECK_ALIVE(VisitForValue(prop->key()));
8854a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      key = Pop();
8855a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    }
8856a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8857a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    CHECK_ALIVE(PushLoad(prop, receiver, key));
8858a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    HValue* function = Pop();
8859a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8860f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (FLAG_hydrogen_track_positions) SetSourcePosition(expr->position());
8861f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
8862a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    // Push the function under the receiver.
8863a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    environment()->SetExpressionStackAt(0, function);
8864a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8865a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    Push(receiver);
8866fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
8867a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    if (function->IsConstant() &&
8868a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        HConstant::cast(function)->handle(isolate())->IsJSFunction()) {
8869a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      Handle<JSFunction> known_function = Handle<JSFunction>::cast(
8870a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org          HConstant::cast(function)->handle(isolate()));
8871a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      expr->set_target(known_function);
8872a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org
88733ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org      if (TryCallApply(expr)) return;
8874a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      CHECK_ALIVE(VisitExpressions(expr->arguments()));
8875a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org
8876a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      Handle<Map> map = types->length() == 1 ? types->first() : Handle<Map>();
88773ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org      if (TryInlineBuiltinMethodCall(expr, receiver, map)) {
887878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org        if (FLAG_trace_inlining) {
887978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org          PrintF("Inlining builtin ");
8880a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org          known_function->ShortPrint();
888178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org          PrintF("\n");
888278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org        }
8883a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        return;
8884a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
88858297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      if (TryInlineApiMethodCall(expr, receiver, types)) return;
88865f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
8887a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      // Wrap the receiver if necessary.
88880a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      if (NeedsWrappingFor(ToType(types->first()), known_function)) {
8889a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        // Since HWrapReceiver currently cannot actually wrap numbers and
8890a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        // strings, use the regular CallFunctionStub for method calls to wrap
8891a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        // the receiver.
8892a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        // TODO(verwaest): Support creation of value wrappers directly in
8893a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        // HWrapReceiver.
8894a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        call = New<HCallFunction>(
8895a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org            function, argument_count, WRAP_AND_CALL);
8896a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      } else if (TryInlineCall(expr)) {
8897a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        return;
88980a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      } else {
8899a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        call = BuildCallConstantFunction(known_function, argument_count);
89000a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      }
8901a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8902a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    } else {
8903a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      CHECK_ALIVE(VisitExpressions(expr->arguments()));
8904a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      CallFunctionFlags flags = receiver->type().IsJSObject()
8905a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org          ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD;
8906a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      call = New<HCallFunction>(function, argument_count, flags);
8907a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
8908a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org    PushArgumentsFromEnvironment(argument_count);
8909a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org
8910a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
8911486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    VariableProxy* proxy = expr->expression()->AsVariableProxy();
8912fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) {
8913594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      return Bailout(kPossibleDirectCallToEval);
891428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    }
891528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
8916bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org    // The function is on the stack in the unoptimized code during
8917bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org    // evaluation of the arguments.
8918bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org    CHECK_ALIVE(VisitForValue(expr->expression()));
8919bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org    HValue* function = Top();
89207e6132b924829c353864933f29124419916db550machenbach@chromium.org    if (expr->global_call()) {
8921486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      Variable* var = proxy->var();
89228f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      bool known_global_function = false;
8923a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // If there is a global property cell for the name at compile time and
8924a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // access check is not enabled we assume that the function will not change
8925a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // and generate optimized code for calling the function.
8926394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      LookupResult lookup(isolate());
8927f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, LOAD);
8928c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      if (type == kUseCell &&
892941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org          !current_info()->global_object()->IsAccessCheckNeeded()) {
893041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org        Handle<GlobalObject> global(current_info()->global_object());
8931c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org        known_global_function = expr->ComputeGlobalTarget(global, &lookup);
89328f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      }
8933a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      if (known_global_function) {
8934a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        Add<HCheckValue>(function, expr->target());
8935e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org
8936a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        // Placeholder for the receiver.
8937a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        Push(graph()->GetConstantUndefined());
8938160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org        CHECK_ALIVE(VisitExpressions(expr->arguments()));
8939a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8940e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org        // Patch the global object on the stack by the expected receiver.
8941e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org        HValue* receiver = ImplicitReceiverFor(function, expr->target());
8942a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        const int receiver_index = argument_count - 1;
8943e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org        environment()->SetExpressionStackAt(receiver_index, receiver);
8944a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8945a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        if (TryInlineBuiltinFunctionCall(expr)) {
894678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org          if (FLAG_trace_inlining) {
894778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org            PrintF("Inlining builtin ");
894878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org            expr->target()->ShortPrint();
894978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org            PrintF("\n");
895078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org          }
895178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org          return;
895278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org        }
8953a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        if (TryInlineApiFunctionCall(expr, receiver)) return;
89547e6132b924829c353864933f29124419916db550machenbach@chromium.org        if (TryHandleArrayCall(expr, function)) return;
8955967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org        if (TryInlineCall(expr)) return;
89567028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
895757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org        PushArgumentsFromEnvironment(argument_count);
8958a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        call = BuildCallConstantFunction(expr->target(), argument_count);
8959a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      } else {
8960bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org        Push(graph()->GetConstantUndefined());
8961bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org        CHECK_ALIVE(VisitExpressions(expr->arguments()));
8962bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org        PushArgumentsFromEnvironment(argument_count);
8963a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org        call = New<HCallFunction>(function, argument_count);
8964a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
8965a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8966c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    } else if (expr->IsMonomorphic()) {
89671f410f9a9c4fbd4270749af64b477df87b753158mstarzinger@chromium.org      Add<HCheckValue>(function, expr->target());
896878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
8969a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      Push(graph()->GetConstantUndefined());
8970e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org      CHECK_ALIVE(VisitExpressions(expr->arguments()));
89719ed27460593e67bc55b9feb15ca7c301e9f804b0rossberg@chromium.org
8972a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      HValue* receiver = ImplicitReceiverFor(function, expr->target());
8973a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      const int receiver_index = argument_count - 1;
8974a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      environment()->SetExpressionStackAt(receiver_index, receiver);
8975a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org
8976a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      if (TryInlineBuiltinFunctionCall(expr)) {
897778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org        if (FLAG_trace_inlining) {
897878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org          PrintF("Inlining builtin ");
897978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org          expr->target()->ShortPrint();
898078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org          PrintF("\n");
898178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org        }
898278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org        return;
898378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      }
8984a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      if (TryInlineApiFunctionCall(expr, receiver)) return;
898578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
8986a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      if (TryInlineCall(expr)) return;
8987a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org
8988a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      call = PreProcessCall(New<HInvokeFunction>(
8989a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org          function, expr->target(), argument_count));
8990c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
8991a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    } else {
8992bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org      Push(graph()->GetConstantUndefined());
8993bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org      CHECK_ALIVE(VisitExpressions(expr->arguments()));
8994bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org      PushArgumentsFromEnvironment(argument_count);
8995a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org      call = New<HCallFunction>(function, argument_count);
8996a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
8997a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
8998a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8999a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  Drop(1);  // Drop the function.
90004f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnInstruction(call, expr->id());
9001a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
9002a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9003a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
90047e6132b924829c353864933f29124419916db550machenbach@chromium.orgvoid HOptimizedGraphBuilder::BuildInlinedCallArray(
90057e6132b924829c353864933f29124419916db550machenbach@chromium.org    Expression* expression,
90067e6132b924829c353864933f29124419916db550machenbach@chromium.org    int argument_count,
90077e6132b924829c353864933f29124419916db550machenbach@chromium.org    Handle<AllocationSite> site) {
90087e6132b924829c353864933f29124419916db550machenbach@chromium.org  ASSERT(!site.is_null());
90097e6132b924829c353864933f29124419916db550machenbach@chromium.org  ASSERT(argument_count >= 0 && argument_count <= 1);
9010b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  NoObservableSideEffectsScope no_effects(this);
9011b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
9012b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  // We should at least have the constructor on the expression stack.
9013b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  HValue* constructor = environment()->ExpressionStackAt(argument_count);
9014b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
901543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  // Register on the site for deoptimization if the transition feedback changes.
90164ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org  AllocationSite::AddDependentCompilationInfo(
90174ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org      site, AllocationSite::TRANSITIONS, top_info());
90187e6132b924829c353864933f29124419916db550machenbach@chromium.org  ElementsKind kind = site->GetElementsKind();
901943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  HInstruction* site_instruction = Add<HConstant>(site);
9020b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
9021b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  // In the single constant argument case, we may have to adjust elements kind
9022b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  // to avoid creating a packed non-empty array.
9023b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (argument_count == 1 && !IsHoleyElementsKind(kind)) {
9024b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    HValue* argument = environment()->Top();
9025b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    if (argument->IsConstant()) {
9026b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      HConstant* constant_argument = HConstant::cast(argument);
9027b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      ASSERT(constant_argument->HasSmiValue());
9028b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      int constant_array_size = constant_argument->Integer32Value();
9029b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      if (constant_array_size != 0) {
9030b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        kind = GetHoleyElementsKind(kind);
9031b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      }
9032b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    }
9033b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  }
9034b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
9035b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  // Build the array.
9036b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  JSArrayBuilder array_builder(this,
9037b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                               kind,
903843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org                               site_instruction,
9039b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                               constructor,
9040b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                               DISABLE_ALLOCATION_SITES);
90417e6132b924829c353864933f29124419916db550machenbach@chromium.org  HValue* new_object = argument_count == 0
90427e6132b924829c353864933f29124419916db550machenbach@chromium.org      ? array_builder.AllocateEmptyArray()
90437e6132b924829c353864933f29124419916db550machenbach@chromium.org      : BuildAllocateArrayFromLength(&array_builder, Top());
90447e6132b924829c353864933f29124419916db550machenbach@chromium.org
90457e6132b924829c353864933f29124419916db550machenbach@chromium.org  int args_to_drop = argument_count + (expression->IsCall() ? 2 : 1);
90467e6132b924829c353864933f29124419916db550machenbach@chromium.org  Drop(args_to_drop);
9047b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  ast_context()->ReturnValue(new_object);
9048b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org}
9049b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
9050b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
9051967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org// Checks whether allocation using the given constructor can be inlined.
9052967e270a034432457500dbf950d2c4951a929e52ulan@chromium.orgstatic bool IsAllocationInlineable(Handle<JSFunction> constructor) {
9053967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  return constructor->has_initial_map() &&
90547d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org      constructor->initial_map()->instance_type() == JS_OBJECT_TYPE &&
905510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org      constructor->initial_map()->instance_size() < HAllocate::kMaxInlineSize &&
905610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org      constructor->initial_map()->InitialPropertiesLength() == 0;
9057967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org}
9058967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org
9059967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org
90607e6132b924829c353864933f29124419916db550machenbach@chromium.orgbool HOptimizedGraphBuilder::IsCallArrayInlineable(
90617e6132b924829c353864933f29124419916db550machenbach@chromium.org    int argument_count,
90627e6132b924829c353864933f29124419916db550machenbach@chromium.org    Handle<AllocationSite> site) {
9063b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Handle<JSFunction> caller = current_info()->closure();
90647e6132b924829c353864933f29124419916db550machenbach@chromium.org  Handle<JSFunction> target = array_function();
9065b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  // We should have the function plus array arguments on the environment stack.
9066b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  ASSERT(environment()->length() >= (argument_count + 1));
9067c8cbc43a1fd5fda5d6a1e172f720cbd1215157c8machenbach@chromium.org  ASSERT(!site.is_null());
9068c8cbc43a1fd5fda5d6a1e172f720cbd1215157c8machenbach@chromium.org
9069f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  bool inline_ok = false;
9070b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (site->CanInlineCall()) {
9071b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    // We also want to avoid inlining in certain 1 argument scenarios.
9072b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    if (argument_count == 1) {
9073b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      HValue* argument = Top();
9074b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      if (argument->IsConstant()) {
9075b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        // Do not inline if the constant length argument is not a smi or
90767e6132b924829c353864933f29124419916db550machenbach@chromium.org        // outside the valid range for unrolled loop initialization.
9077b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        HConstant* constant_argument = HConstant::cast(argument);
9078b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        if (constant_argument->HasSmiValue()) {
9079b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org          int value = constant_argument->Integer32Value();
90807e6132b924829c353864933f29124419916db550machenbach@chromium.org          inline_ok = value >= 0 && value <= kElementLoopUnrollThreshold;
9081b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org          if (!inline_ok) {
9082b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org            TraceInline(target, caller,
90837e6132b924829c353864933f29124419916db550machenbach@chromium.org                        "Constant length outside of valid inlining range.");
9084b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org          }
9085b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        }
9086b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      } else {
90877e6132b924829c353864933f29124419916db550machenbach@chromium.org        TraceInline(target, caller,
90887e6132b924829c353864933f29124419916db550machenbach@chromium.org                    "Dont inline [new] Array(n) where n isn't constant.");
9089b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      }
90907e6132b924829c353864933f29124419916db550machenbach@chromium.org    } else if (argument_count == 0) {
9091ed50beee6c90dc00e0f746de915014f57eaeccbdmachenbach@chromium.org      inline_ok = true;
90927e6132b924829c353864933f29124419916db550machenbach@chromium.org    } else {
90937e6132b924829c353864933f29124419916db550machenbach@chromium.org      TraceInline(target, caller, "Too many arguments to inline.");
9094b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    }
9095b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  } else {
9096b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    TraceInline(target, caller, "AllocationSite requested no inlining.");
9097b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  }
9098b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
9099b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (inline_ok) {
9100b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    TraceInline(target, caller, NULL);
9101b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  }
9102b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  return inline_ok;
9103b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org}
9104b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
9105b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
9106a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) {
9107160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
9108160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
9109160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
9110f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position());
9111967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  int argument_count = expr->arguments()->length() + 1;  // Plus constructor.
911210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  Factory* factory = isolate()->factory();
9113496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
9114b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  // The constructor function is on the stack in the unoptimized code
9115b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  // during evaluation of the arguments.
9116b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  CHECK_ALIVE(VisitForValue(expr->expression()));
9117b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  HValue* function = Top();
9118b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  CHECK_ALIVE(VisitExpressions(expr->arguments()));
9119b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
9120967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  if (FLAG_inline_construct &&
9121967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      expr->IsMonomorphic() &&
9122967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      IsAllocationInlineable(expr->target())) {
9123967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    Handle<JSFunction> constructor = expr->target();
91241f410f9a9c4fbd4270749af64b477df87b753158mstarzinger@chromium.org    HValue* check = Add<HCheckValue>(function, constructor);
912535814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org
912635814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org    // Force completion of inobject slack tracking before generating
912735814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org    // allocation code to finalize instance size.
9128011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org    if (constructor->IsInobjectSlackTrackingInProgress()) {
9129011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org      constructor->CompleteInobjectSlackTracking();
913035814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org    }
9131967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org
913210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    // Calculate instance size from initial map of constructor.
913310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    ASSERT(constructor->has_initial_map());
913410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    Handle<Map> initial_map(constructor->initial_map());
913510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    int instance_size = initial_map->instance_size();
913610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    ASSERT(initial_map->InitialPropertiesLength() == 0);
913710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
913810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    // Allocate an instance of the implicit receiver object.
913910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    HValue* size_in_bytes = Add<HConstant>(instance_size);
914069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org    HAllocationMode allocation_mode;
914169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org    if (FLAG_pretenuring_call_new) {
914269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org      if (FLAG_allocation_site_pretenuring) {
914369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org        // Try to use pretenuring feedback.
914469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org        Handle<AllocationSite> allocation_site = expr->allocation_site();
914569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org        allocation_mode = HAllocationMode(allocation_site);
914669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org        // Take a dependency on allocation site.
914769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org        AllocationSite::AddDependentCompilationInfo(allocation_site,
914869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org                                                    AllocationSite::TENURING,
914969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org                                                    top_info());
915069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org      }
915169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org    }
915269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org
9153011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org    HAllocate* receiver = BuildAllocate(
9154011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org        size_in_bytes, HType::JSObject(), JS_OBJECT_TYPE, allocation_mode);
915510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    receiver->set_known_initial_map(initial_map);
915610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
915710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    // Initialize map and fields of the newly allocated object.
915810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    { NoObservableSideEffectsScope no_effects(this);
915910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org      ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE);
9160d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      Add<HStoreNamedField>(receiver,
91610a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org          HObjectAccess::ForMapAndOffset(initial_map, JSObject::kMapOffset),
9162011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org          Add<HConstant>(initial_map));
916310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org      HValue* empty_fixed_array = Add<HConstant>(factory->empty_fixed_array());
9164d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      Add<HStoreNamedField>(receiver,
91650a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org          HObjectAccess::ForMapAndOffset(initial_map,
91660a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                                         JSObject::kPropertiesOffset),
91670a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org          empty_fixed_array);
9168d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      Add<HStoreNamedField>(receiver,
91690a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org          HObjectAccess::ForMapAndOffset(initial_map,
91700a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                                         JSObject::kElementsOffset),
91710a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org          empty_fixed_array);
917210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org      if (initial_map->inobject_properties() != 0) {
917310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org        HConstant* undefined = graph()->GetConstantUndefined();
917410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org        for (int i = 0; i < initial_map->inobject_properties(); i++) {
91750a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org          int property_offset = initial_map->GetInObjectPropertyOffset(i);
9176d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          Add<HStoreNamedField>(receiver,
91770a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org              HObjectAccess::ForMapAndOffset(initial_map, property_offset),
91780a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org              undefined);
917910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org        }
918010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org      }
918110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    }
918210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
918310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    // Replace the constructor function with a newly allocated receiver using
918410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    // the index of the receiver from the top of the expression stack.
9185967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    const int receiver_index = argument_count - 1;
9186967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    ASSERT(environment()->ExpressionStackAt(receiver_index) == function);
9187967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    environment()->SetExpressionStackAt(receiver_index, receiver);
9188967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org
9189011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org    if (TryInlineConstruct(expr, receiver)) {
9190011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org      // Inlining worked, add a dependency on the initial map to make sure that
9191011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org      // this code is deoptimized whenever the initial map of the constructor
9192011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org      // changes.
9193011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org      Map::AddDependentCompilationInfo(
9194011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org          initial_map, DependentCode::kInitialMapChangedGroup, top_info());
9195011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org      return;
9196011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org    }
9197967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org
919810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    // TODO(mstarzinger): For now we remove the previous HAllocate and all
9199011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org    // corresponding instructions and instead add HPushArguments for the
920010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    // arguments in case inlining failed.  What we actually should do is for
920110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    // inlining to try to build a subgraph without mutating the parent graph.
920210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    HInstruction* instr = current_block()->last();
9203011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org    do {
920410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org      HInstruction* prev_instr = instr->previous();
920510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org      instr->DeleteAndReplaceWith(NULL);
920610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org      instr = prev_instr;
9207011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org    } while (instr != check);
9208967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    environment()->SetExpressionStackAt(receiver_index, function);
92098e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org    HInstruction* call =
92108e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org      PreProcessCall(New<HCallNew>(function, argument_count));
9211967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    return ast_context()->ReturnInstruction(call, expr->id());
9212967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  } else {
9213967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    // The constructor function is both an operand to the instruction and an
9214967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    // argument to the construct call.
92157e6132b924829c353864933f29124419916db550machenbach@chromium.org    if (TryHandleArrayCallNew(expr, function)) return;
9216b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
92177e6132b924829c353864933f29124419916db550machenbach@chromium.org    HInstruction* call =
92187e6132b924829c353864933f29124419916db550machenbach@chromium.org        PreProcessCall(New<HCallNew>(function, argument_count));
9219967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    return ast_context()->ReturnInstruction(call, expr->id());
9220967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  }
9221a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
9222a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9223a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9224a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Support for generating inlined runtime functions.
9225a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9226a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org// Lookup table for generators for runtime calls that are generated inline.
9227a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org// Elements of the table are member pointers to functions of
9228a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org// HOptimizedGraphBuilder.
92295f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org#define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize)  \
9230a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    &HOptimizedGraphBuilder::Generate##Name,
9231a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9232a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgconst HOptimizedGraphBuilder::InlineFunctionGenerator
9233a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    HOptimizedGraphBuilder::kInlineFunctionGenerators[] = {
9234a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
92359b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org        INLINE_OPTIMIZED_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
9236a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
9237a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#undef INLINE_FUNCTION_GENERATOR_ADDRESS
9238a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9239a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
924037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.orgtemplate <class ViewClass>
924137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.orgvoid HGraphBuilder::BuildArrayBufferViewInitialization(
924237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    HValue* obj,
924337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    HValue* buffer,
924437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    HValue* byte_offset,
924537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    HValue* byte_length) {
924637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
924737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  for (int offset = ViewClass::kSize;
924837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org       offset < ViewClass::kSizeWithInternalFields;
924937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org       offset += kPointerSize) {
925037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    Add<HStoreNamedField>(obj,
92510a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org        HObjectAccess::ForObservableJSObjectOffset(offset),
92520a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org        graph()->GetConstant0());
925337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  }
925437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
925537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  Add<HStoreNamedField>(
925637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      obj,
925737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      HObjectAccess::ForJSArrayBufferViewByteOffset(),
92580a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      byte_offset);
925937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  Add<HStoreNamedField>(
926037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      obj,
926137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      HObjectAccess::ForJSArrayBufferViewByteLength(),
92620a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      byte_length);
926337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
9264895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  if (buffer != NULL) {
9265895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    Add<HStoreNamedField>(
9266895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        obj,
9267895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        HObjectAccess::ForJSArrayBufferViewBuffer(), buffer);
9268895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    HObjectAccess weak_first_view_access =
9269895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        HObjectAccess::ForJSArrayBufferWeakFirstView();
9270895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    Add<HStoreNamedField>(obj,
9271895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        HObjectAccess::ForJSArrayBufferViewWeakNext(),
9272895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        Add<HLoadNamedField>(buffer,
9273895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org                             static_cast<HValue*>(NULL),
9274895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org                             weak_first_view_access));
9275895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    Add<HStoreNamedField>(buffer, weak_first_view_access, obj);
9276895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  } else {
9277895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    Add<HStoreNamedField>(
9278895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        obj,
9279895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        HObjectAccess::ForJSArrayBufferViewBuffer(),
9280895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        Add<HConstant>(static_cast<int32_t>(0)));
9281895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    Add<HStoreNamedField>(obj,
9282895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        HObjectAccess::ForJSArrayBufferViewWeakNext(),
9283895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        graph()->GetConstantUndefined());
9284895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  }
928537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org}
928637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
928737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
9288a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateDataViewInitialize(
9289af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    CallRuntime* expr) {
9290af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  ZoneList<Expression*>* arguments = expr->arguments();
9291af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
9292af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  ASSERT(arguments->length()== 4);
9293af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  CHECK_ALIVE(VisitForValue(arguments->at(0)));
9294af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  HValue* obj = Pop();
9295af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
9296af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  CHECK_ALIVE(VisitForValue(arguments->at(1)));
9297af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  HValue* buffer = Pop();
9298af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
9299af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  CHECK_ALIVE(VisitForValue(arguments->at(2)));
9300af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  HValue* byte_offset = Pop();
9301af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
9302af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  CHECK_ALIVE(VisitForValue(arguments->at(3)));
9303af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  HValue* byte_length = Pop();
9304af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
9305eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org  {
9306eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org    NoObservableSideEffectsScope scope(this);
9307eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org    BuildArrayBufferViewInitialization<JSDataView>(
9308eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org        obj, buffer, byte_offset, byte_length);
9309eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org  }
931037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org}
931137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
931237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
9313895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.orgstatic Handle<Map> TypedArrayMap(Isolate* isolate,
9314895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org                                 ExternalArrayType array_type,
9315895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org                                 ElementsKind target_kind) {
9316895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  Handle<Context> native_context = isolate->native_context();
9317895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  Handle<JSFunction> fun;
9318895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  switch (array_type) {
9319895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                       \
9320895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    case kExternal##Type##Array:                                              \
9321895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      fun = Handle<JSFunction>(native_context->type##_array_fun());           \
9322895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      break;
9323895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
9324895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    TYPED_ARRAYS(TYPED_ARRAY_CASE)
9325895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org#undef TYPED_ARRAY_CASE
9326895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  }
9327895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  Handle<Map> map(fun->initial_map());
9328895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  return Map::AsElementsKind(map, target_kind);
9329895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org}
9330895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
9331895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
9332895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.orgHValue* HOptimizedGraphBuilder::BuildAllocateExternalElements(
9333895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    ExternalArrayType array_type,
9334895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    bool is_zero_byte_offset,
9335895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    HValue* buffer, HValue* byte_offset, HValue* length) {
9336895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  Handle<Map> external_array_map(
9337895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      isolate()->heap()->MapForExternalArrayType(array_type));
93382f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org
93392f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  // The HForceRepresentation is to prevent possible deopt on int-smi
93402f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  // conversion after allocation but before the new object fields are set.
93412f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  length = AddUncasted<HForceRepresentation>(length, Representation::Smi());
9342895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  HValue* elements =
9343895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      Add<HAllocate>(
9344895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org          Add<HConstant>(ExternalArray::kAlignedSize),
9345eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org          HType::HeapObject(),
9346895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org          NOT_TENURED,
9347895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org          external_array_map->instance_type());
9348895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
9349895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  AddStoreMapConstant(elements, external_array_map);
93502f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  Add<HStoreNamedField>(elements,
93512f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org      HObjectAccess::ForFixedArrayLength(), length);
9352895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
9353895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  HValue* backing_store = Add<HLoadNamedField>(
9354895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      buffer, static_cast<HValue*>(NULL),
9355895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      HObjectAccess::ForJSArrayBufferBackingStore());
9356895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
9357895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  HValue* typed_array_start;
9358895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  if (is_zero_byte_offset) {
9359895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    typed_array_start = backing_store;
9360895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  } else {
9361895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    HInstruction* external_pointer =
9362895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        AddUncasted<HAdd>(backing_store, byte_offset);
9363895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    // Arguments are checked prior to call to TypedArrayInitialize,
9364895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    // including byte_offset.
9365895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    external_pointer->ClearFlag(HValue::kCanOverflow);
9366895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    typed_array_start = external_pointer;
9367895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  }
9368895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
9369895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  Add<HStoreNamedField>(elements,
9370895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      HObjectAccess::ForExternalArrayExternalPointer(),
9371895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      typed_array_start);
9372895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
9373895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  return elements;
9374895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org}
9375895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
9376895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
9377895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.orgHValue* HOptimizedGraphBuilder::BuildAllocateFixedTypedArray(
9378895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    ExternalArrayType array_type, size_t element_size,
9379895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    ElementsKind fixed_elements_kind,
9380895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    HValue* byte_length, HValue* length) {
9381895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  STATIC_ASSERT(
9382895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      (FixedTypedArrayBase::kHeaderSize & kObjectAlignmentMask) == 0);
9383895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  HValue* total_size;
9384895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
9385895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  // if fixed array's elements are not aligned to object's alignment,
9386895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  // we need to align the whole array to object alignment.
9387895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  if (element_size % kObjectAlignment != 0) {
9388895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    total_size = BuildObjectSizeAlignment(
9389895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        byte_length, FixedTypedArrayBase::kHeaderSize);
9390895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  } else {
9391895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    total_size = AddUncasted<HAdd>(byte_length,
9392895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        Add<HConstant>(FixedTypedArrayBase::kHeaderSize));
9393895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    total_size->ClearFlag(HValue::kCanOverflow);
9394895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  }
9395895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
93962f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  // The HForceRepresentation is to prevent possible deopt on int-smi
93972f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  // conversion after allocation but before the new object fields are set.
93982f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  length = AddUncasted<HForceRepresentation>(length, Representation::Smi());
9399895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  Handle<Map> fixed_typed_array_map(
9400895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      isolate()->heap()->MapForFixedTypedArray(array_type));
9401895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  HValue* elements =
9402eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org      Add<HAllocate>(total_size, HType::HeapObject(),
94036a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org                     NOT_TENURED, fixed_typed_array_map->instance_type());
9404895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  AddStoreMapConstant(elements, fixed_typed_array_map);
9405895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
9406895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  Add<HStoreNamedField>(elements,
9407895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      HObjectAccess::ForFixedArrayLength(),
9408895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      length);
94092f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org
9410895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  HValue* filler = Add<HConstant>(static_cast<int32_t>(0));
9411895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
9412895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  {
9413895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement);
9414895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
9415895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    HValue* key = builder.BeginBody(
9416895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        Add<HConstant>(static_cast<int32_t>(0)),
9417895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        length, Token::LT);
9418895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    Add<HStoreKeyed>(elements, key, filler, fixed_elements_kind);
9419895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
9420895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    builder.EndBody();
9421895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  }
9422895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  return elements;
9423895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org}
9424895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
9425895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
9426a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateTypedArrayInitialize(
942737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    CallRuntime* expr) {
942837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  ZoneList<Expression*>* arguments = expr->arguments();
942937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
943037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  static const int kObjectArg = 0;
943137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  static const int kArrayIdArg = 1;
943237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  static const int kBufferArg = 2;
943337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  static const int kByteOffsetArg = 3;
943437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  static const int kByteLengthArg = 4;
943537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  static const int kArgsLength = 5;
943637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  ASSERT(arguments->length() == kArgsLength);
943737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
943837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
943937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  CHECK_ALIVE(VisitForValue(arguments->at(kObjectArg)));
944037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  HValue* obj = Pop();
944137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
9442196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (arguments->at(kArrayIdArg)->IsLiteral()) {
9443a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    // This should never happen in real use, but can happen when fuzzing.
9444a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    // Just bail out.
9445a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    Bailout(kNeedSmiLiteral);
9446a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    return;
9447a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  }
944837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  Handle<Object> value =
944937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      static_cast<Literal*>(arguments->at(kArrayIdArg))->value();
9450a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  if (!value->IsSmi()) {
9451a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    // This should never happen in real use, but can happen when fuzzing.
9452a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    // Just bail out.
9453a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    Bailout(kNeedSmiLiteral);
9454a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    return;
9455a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  }
945637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  int array_id = Smi::cast(*value)->value();
945737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
9458895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  HValue* buffer;
9459895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  if (!arguments->at(kBufferArg)->IsNullLiteral()) {
9460895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    CHECK_ALIVE(VisitForValue(arguments->at(kBufferArg)));
9461895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    buffer = Pop();
9462895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  } else {
9463895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    buffer = NULL;
9464895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  }
946537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
946637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  HValue* byte_offset;
946737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  bool is_zero_byte_offset;
946837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
9469196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  if (arguments->at(kByteOffsetArg)->IsLiteral()
947037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      && Smi::FromInt(0) ==
947137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      *static_cast<Literal*>(arguments->at(kByteOffsetArg))->value()) {
947237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    byte_offset = Add<HConstant>(static_cast<int32_t>(0));
947337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    is_zero_byte_offset = true;
947437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  } else {
947537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    CHECK_ALIVE(VisitForValue(arguments->at(kByteOffsetArg)));
947637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    byte_offset = Pop();
947737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    is_zero_byte_offset = false;
9478895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    ASSERT(buffer != NULL);
9479af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  }
9480af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
948137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  CHECK_ALIVE(VisitForValue(arguments->at(kByteLengthArg)));
948237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  HValue* byte_length = Pop();
9483af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
9484eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org  NoObservableSideEffectsScope scope(this);
948537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  IfBuilder byte_offset_smi(this);
948637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
948737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  if (!is_zero_byte_offset) {
948837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    byte_offset_smi.If<HIsSmiAndBranch>(byte_offset);
948937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    byte_offset_smi.Then();
949037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  }
949137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
9492895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  ExternalArrayType array_type =
9493895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      kExternalInt8Array;  // Bogus initialization.
9494895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  size_t element_size = 1;  // Bogus initialization.
9495895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  ElementsKind external_elements_kind =  // Bogus initialization.
9496895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      EXTERNAL_INT8_ELEMENTS;
9497895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  ElementsKind fixed_elements_kind =  // Bogus initialization.
9498895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      INT8_ELEMENTS;
9499895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  Runtime::ArrayIdToTypeAndSize(array_id,
9500895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      &array_type,
9501895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      &external_elements_kind,
9502895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      &fixed_elements_kind,
9503895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      &element_size);
9504895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
9505895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
950637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  { //  byte_offset is Smi.
950737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    BuildArrayBufferViewInitialization<JSTypedArray>(
950837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        obj, buffer, byte_offset, byte_length);
950937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
951037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
951137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    HInstruction* length = AddUncasted<HDiv>(byte_length,
951237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        Add<HConstant>(static_cast<int32_t>(element_size)));
951337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
951437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    Add<HStoreNamedField>(obj,
951537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org        HObjectAccess::ForJSTypedArrayLength(),
95160a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org        length);
95170a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org
9518895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    HValue* elements;
9519895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    if (buffer != NULL) {
9520895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      elements = BuildAllocateExternalElements(
9521895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org          array_type, is_zero_byte_offset, buffer, byte_offset, length);
9522895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      Handle<Map> obj_map = TypedArrayMap(
9523895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org          isolate(), array_type, external_elements_kind);
9524895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      AddStoreMapConstant(obj, obj_map);
952537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    } else {
9526895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      ASSERT(is_zero_byte_offset);
9527895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org      elements = BuildAllocateFixedTypedArray(
9528895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org          array_type, element_size, fixed_elements_kind,
9529895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org          byte_length, length);
9530895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    }
953137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    Add<HStoreNamedField>(
95320a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org        obj, HObjectAccess::ForElementsPointer(), elements);
953337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  }
953437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
953537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  if (!is_zero_byte_offset) {
953637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    byte_offset_smi.Else();
953737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    { //  byte_offset is not Smi.
9538bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org      Push(obj);
9539bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org      CHECK_ALIVE(VisitForValue(arguments->at(kArrayIdArg)));
9540bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org      Push(buffer);
9541bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org      Push(byte_offset);
9542bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org      Push(byte_length);
9543bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org      PushArgumentsFromEnvironment(kArgsLength);
954437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org      Add<HCallRuntime>(expr->name(), expr->function(), kArgsLength);
954537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    }
954637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  }
954737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  byte_offset_smi.End();
9548af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org}
9549af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
9550af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
9551a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateMaxSmi(CallRuntime* expr) {
9552a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  ASSERT(expr->arguments()->length() == 0);
9553a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  HConstant* max_smi = New<HConstant>(static_cast<int32_t>(Smi::kMaxValue));
9554a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  return ast_context()->ReturnInstruction(max_smi, expr->id());
9555a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org}
9556a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org
9557a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org
9558895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateTypedArrayMaxSizeInHeap(
9559895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org    CallRuntime* expr) {
9560895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  ASSERT(expr->arguments()->length() == 0);
9561895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  HConstant* result = New<HConstant>(static_cast<int32_t>(
9562895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org        FLAG_typed_array_max_size_in_heap));
9563895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  return ast_context()->ReturnInstruction(result, expr->id());
9564895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org}
9565895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
9566895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
95672f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateArrayBufferGetByteLength(
95682f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    CallRuntime* expr) {
95692f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  ASSERT(expr->arguments()->length() == 1);
95702f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
95712f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  HValue* buffer = Pop();
95722f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  HInstruction* result = New<HLoadNamedField>(
95732f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    buffer,
95742f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    static_cast<HValue*>(NULL),
95752f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    HObjectAccess::ForJSArrayBufferByteLength());
95762f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  return ast_context()->ReturnInstruction(result, expr->id());
95772f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org}
95782f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org
95792f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org
95802f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteLength(
95812f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    CallRuntime* expr) {
95822f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  ASSERT(expr->arguments()->length() == 1);
95832f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
95842f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  HValue* buffer = Pop();
95852f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  HInstruction* result = New<HLoadNamedField>(
95862f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    buffer,
95872f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    static_cast<HValue*>(NULL),
95882f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    HObjectAccess::ForJSArrayBufferViewByteLength());
95892f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  return ast_context()->ReturnInstruction(result, expr->id());
95902f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org}
95912f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org
95922f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org
95932f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteOffset(
95942f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    CallRuntime* expr) {
95952f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  ASSERT(expr->arguments()->length() == 1);
95962f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
95972f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  HValue* buffer = Pop();
95982f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  HInstruction* result = New<HLoadNamedField>(
95992f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    buffer,
96002f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    static_cast<HValue*>(NULL),
96012f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    HObjectAccess::ForJSArrayBufferViewByteOffset());
96022f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  return ast_context()->ReturnInstruction(result, expr->id());
96032f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org}
96042f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org
96052f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org
96062f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateTypedArrayGetLength(
96072f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    CallRuntime* expr) {
96082f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  ASSERT(expr->arguments()->length() == 1);
96092f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
96102f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  HValue* buffer = Pop();
96112f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  HInstruction* result = New<HLoadNamedField>(
96122f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    buffer,
96132f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    static_cast<HValue*>(NULL),
96142f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org    HObjectAccess::ForJSTypedArrayLength());
96152f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  return ast_context()->ReturnInstruction(result, expr->id());
96162f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org}
96172f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org
96182f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org
9619a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
9620160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
9621160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
9622160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
9623a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (expr->is_jsruntime()) {
9624594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return Bailout(kCallToAJavaScriptRuntimeFunction);
9625a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
9626a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9627ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  const Runtime::Function* function = expr->function();
96283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(function != NULL);
9629af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
96309b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org  if (function->intrinsic_type == Runtime::INLINE ||
96319b95fd75bfb24acf6b51a360058331013e74fc73machenbach@chromium.org      function->intrinsic_type == Runtime::INLINE_OPTIMIZED) {
96323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    ASSERT(expr->name()->length() > 0);
96333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    ASSERT(expr->name()->Get(0) == '_');
9634a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Call to an inline function.
9635a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    int lookup_index = static_cast<int>(function->function_id) -
9636a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        static_cast<int>(Runtime::kFirstInlineFunction);
9637a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(lookup_index >= 0);
9638a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(static_cast<size_t>(lookup_index) <
9639a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org           ARRAY_SIZE(kInlineFunctionGenerators));
9640a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index];
9641a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9642a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Call the inline code generator using the pointer-to-member.
96433a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    (this->*generator)(expr);
9644a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
9645a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ASSERT(function->intrinsic_type == Runtime::RUNTIME);
96463a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    Handle<String> name = expr->name();
96473a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    int argument_count = expr->arguments()->length();
9648bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org    CHECK_ALIVE(VisitExpressions(expr->arguments()));
9649bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org    PushArgumentsFromEnvironment(argument_count);
9650d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    HCallRuntime* call = New<HCallRuntime>(name, function,
9651d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                                           argument_count);
96524f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    return ast_context()->ReturnInstruction(call, expr->id());
9653a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
9654a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
9655a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9656a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9657a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
9658160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
9659160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
9660160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
966183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  switch (expr->op()) {
966283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    case Token::DELETE: return VisitDelete(expr);
966383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    case Token::VOID: return VisitVoid(expr);
966483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    case Token::TYPEOF: return VisitTypeof(expr);
966583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    case Token::NOT: return VisitNot(expr);
966683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    default: UNREACHABLE();
966783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
966883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
966983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
9670c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
9671a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) {
967283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Property* prop = expr->expression()->AsProperty();
9673486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  VariableProxy* proxy = expr->expression()->AsVariableProxy();
9674486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  if (prop != NULL) {
96754668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    CHECK_ALIVE(VisitForValue(prop->obj()));
96764668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    CHECK_ALIVE(VisitForValue(prop->key()));
96774668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    HValue* key = Pop();
96784668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    HValue* obj = Pop();
9679d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    HValue* function = AddLoadJSBuiltin(Builtins::DELETE);
96808d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    Add<HPushArguments>(obj, key, Add<HConstant>(function_strict_mode()));
9681bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    // TODO(olivf) InvokeFunction produces a check for the parameter count,
9682bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    // even though we are certain to pass the correct number of arguments here.
9683d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    HInstruction* instr = New<HInvokeFunction>(function, 3);
96844668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org    return ast_context()->ReturnInstruction(instr, expr->id());
9685486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  } else if (proxy != NULL) {
9686486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    Variable* var = proxy->var();
9687486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    if (var->IsUnallocated()) {
9688594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      Bailout(kDeleteWithGlobalVariable);
9689486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    } else if (var->IsStackAllocated() || var->IsContextSlot()) {
9690486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      // Result of deleting non-global variables is false.  'this' is not
9691486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      // really a variable, though we implement it as one.  The
9692486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      // subexpression does not have side effects.
9693486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      HValue* value = var->is_this()
9694486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org          ? graph()->GetConstantTrue()
9695486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org          : graph()->GetConstantFalse();
9696486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      return ast_context()->ReturnValue(value);
9697486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    } else {
9698594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      Bailout(kDeleteWithNonGlobalVariable);
9699486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    }
970083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  } else {
9701486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    // Result of deleting non-property, non-variable reference is true.
9702486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    // Evaluate the subexpression for side effects.
9703486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    CHECK_ALIVE(VisitForEffect(expr->expression()));
9704486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    return ast_context()->ReturnValue(graph()->GetConstantTrue());
970583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
970683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
97078f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
97088f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
9709a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitVoid(UnaryOperation* expr) {
971083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  CHECK_ALIVE(VisitForEffect(expr->expression()));
97114f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnValue(graph()->GetConstantUndefined());
971283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
97133a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
9714badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
9715a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitTypeof(UnaryOperation* expr) {
971683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  CHECK_ALIVE(VisitForTypeOf(expr->expression()));
971783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  HValue* value = Pop();
97188e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  HInstruction* instr = New<HTypeof>(value);
9719ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  return ast_context()->ReturnInstruction(instr, expr->id());
972083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
972183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
972283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
9723a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) {
972483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (ast_context()->IsTest()) {
972583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    TestContext* context = TestContext::cast(ast_context());
972683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    VisitForControl(expr->expression(),
972783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                    context->if_false(),
972883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                    context->if_true());
972983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    return;
973083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
973183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
973283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (ast_context()->IsEffect()) {
973383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    VisitForEffect(expr->expression());
973483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    return;
973583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
973683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
973783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ASSERT(ast_context()->IsValue());
973883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  HBasicBlock* materialize_false = graph()->CreateBasicBlock();
973983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  HBasicBlock* materialize_true = graph()->CreateBasicBlock();
974083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  CHECK_BAILOUT(VisitForControl(expr->expression(),
974183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                materialize_false,
974283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                materialize_true));
974383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
974483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (materialize_false->HasPredecessor()) {
9745c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    materialize_false->SetJoinId(expr->MaterializeFalseId());
974683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    set_current_block(materialize_false);
974783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Push(graph()->GetConstantFalse());
9748badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  } else {
974983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    materialize_false = NULL;
975083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
975183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
975283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (materialize_true->HasPredecessor()) {
9753c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    materialize_true->SetJoinId(expr->MaterializeTrueId());
975483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    set_current_block(materialize_true);
975583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Push(graph()->GetConstantTrue());
975683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  } else {
975783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    materialize_true = NULL;
9758a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
975983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
976083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  HBasicBlock* join =
976183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    CreateJoin(materialize_false, materialize_true, expr->id());
976283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  set_current_block(join);
97634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  if (join != NULL) return ast_context()->ReturnValue(Pop());
9764a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
9765a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9766a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9767a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHInstruction* HOptimizedGraphBuilder::BuildIncrement(
9768a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    bool returns_original_input,
9769a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    CountOperation* expr) {
9770c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // The input to the count operation is on top of the expression stack.
97716d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  Representation rep = Representation::FromType(expr->type());
97721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (rep.IsNone() || rep.IsTagged()) {
9773ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    rep = Representation::Smi();
97748e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  }
9775c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
9776c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  if (returns_original_input) {
9777c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    // We need an explicit HValue representing ToNumber(input).  The
9778c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    // actual HChange instruction we need is (sometimes) added in a later
9779c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    // phase, so it is not available now to be used as an input to HAdd and
9780c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    // as the return value.
97819af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org    HInstruction* number_input = AddUncasted<HForceRepresentation>(Pop(), rep);
97821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    if (!rep.IsDouble()) {
97831510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      number_input->SetFlag(HInstruction::kFlexibleRepresentation);
97841510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      number_input->SetFlag(HInstruction::kCannotBeTagged);
97851510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    }
9786c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    Push(number_input);
9787c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  }
9788c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
9789c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // The addition has no side effects, so we do not need
9790c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // to simulate the expression stack after this instruction.
9791c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // Any later failures deopt to the load of the input or earlier.
9792c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  HConstant* delta = (expr->op() == Token::INC)
9793a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      ? graph()->GetConstant1()
9794a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      : graph()->GetConstantMinus1();
9795662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  HInstruction* instr = AddUncasted<HAdd>(Top(), delta);
9796662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  if (instr->IsAdd()) {
9797662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    HAdd* add = HAdd::cast(instr);
9798662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    add->set_observed_input_representation(1, rep);
9799662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    add->set_observed_input_representation(2, Representation::Smi());
9800662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  }
98011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  instr->SetFlag(HInstruction::kCannotBeTagged);
9802fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  instr->ClearAllSideEffects();
9803a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return instr;
9804a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
9805a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9806a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9807639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.orgvoid HOptimizedGraphBuilder::BuildStoreForEffect(Expression* expr,
9808639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                                                 Property* prop,
9809639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                                                 BailoutId ast_id,
9810639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                                                 BailoutId return_id,
9811639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                                                 HValue* object,
9812639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                                                 HValue* key,
9813639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                                                 HValue* value) {
98142c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org  EffectContext for_effect(this);
98152c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org  Push(object);
9816639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  if (key != NULL) Push(key);
98172c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org  Push(value);
9818639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  BuildStore(expr, prop, ast_id, return_id);
98192c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org}
98202c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org
98212c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org
9822a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) {
9823160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
9824160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
9825160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
9826f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position());
982744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  Expression* target = expr->expression();
9828a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  VariableProxy* proxy = target->AsVariableProxy();
9829a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Property* prop = target->AsProperty();
9830486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  if (proxy == NULL && prop == NULL) {
9831594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return Bailout(kInvalidLhsInCountOperation);
9832c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  }
9833c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
9834c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // Match the full code generator stack by simulating an extra stack
9835c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // element for postfix operations in a non-effect context.  The return
9836c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // value is ToNumber(input).
9837c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  bool returns_original_input =
9838c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org      expr->is_postfix() && !ast_context()->IsEffect();
9839c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  HValue* input = NULL;  // ToNumber(original_input).
9840c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  HValue* after = NULL;  // The result after incrementing or decrementing.
9841a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9842486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org  if (proxy != NULL) {
9843486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    Variable* var = proxy->var();
9844486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    if (var->mode() == CONST_LEGACY)  {
9845594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      return Bailout(kUnsupportedCountOperationWithConst);
9846d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org    }
9847c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    // Argument of the count operation is a variable, not a property.
9848c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    ASSERT(prop == NULL);
9849160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    CHECK_ALIVE(VisitForValue(target));
9850a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9851c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    after = BuildIncrement(returns_original_input, expr);
9852c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    input = returns_original_input ? Top() : Pop();
98535f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    Push(after);
9854a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9855486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    switch (var->location()) {
9856486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      case Variable::UNALLOCATED:
9857486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        HandleGlobalVariableAssignment(var,
9858486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org                                       after,
9859486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org                                       expr->AssignmentId());
9860486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        break;
9861486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
9862486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      case Variable::PARAMETER:
9863486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      case Variable::LOCAL:
9864d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org        BindIfLive(var, after);
9865486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        break;
9866486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
9867486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      case Variable::CONTEXT: {
9868486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        // Bail out if we try to mutate a parameter value in a function
9869486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        // using the arguments object.  We do not (yet) correctly handle the
9870486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        // arguments property of the function.
987141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org        if (current_info()->scope()->arguments() != NULL) {
9872486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org          // Parameters will rewrite to context slots.  We have no direct
9873486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org          // way to detect that the variable is a parameter so we use a
9874486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org          // linear search of the parameter list.
987541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org          int count = current_info()->scope()->num_parameters();
9876486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org          for (int i = 0; i < count; ++i) {
987741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org            if (var == current_info()->scope()->parameter(i)) {
9878594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org              return Bailout(kAssignmentToParameterInArgumentsObject);
9879486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org            }
98807b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org          }
98817b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org        }
9882486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org
9883486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        HValue* context = BuildContextChainWalk(var);
9884355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org        HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode())
98857ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org            ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck;
98861510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(),
98871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                                          mode, after);
9888c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        if (instr->HasObservableSideEffects()) {
9889c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org          Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
9890c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        }
9891486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org        break;
98927b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      }
98937b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
9894486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      case Variable::LOOKUP:
9895594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org        return Bailout(kLookupVariableInCountOperation);
9896a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
9897a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9898639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    Drop(returns_original_input ? 2 : 1);
9899639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    return ast_context()->ReturnValue(expr->is_postfix() ? input : after);
9900639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  }
9901a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9902639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  // Argument of the count operation is a property.
9903639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  ASSERT(prop != NULL);
9904639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  if (returns_original_input) Push(graph()->GetConstantUndefined());
9905a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9906639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  CHECK_ALIVE(VisitForValue(prop->obj()));
9907639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  HValue* object = Top();
9908a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9909639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  HValue* key = NULL;
9910528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if ((!prop->IsFunctionPrototype() && !prop->key()->IsPropertyName()) ||
9911639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org      prop->IsStringAccess()) {
9912639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    CHECK_ALIVE(VisitForValue(prop->key()));
9913639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    key = Top();
9914639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  }
99153d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org
991671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  CHECK_ALIVE(PushLoad(prop, object, key));
9917a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9918639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  after = BuildIncrement(returns_original_input, expr);
9919a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9920639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  if (returns_original_input) {
9921639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    input = Pop();
9922639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    // Drop object and key to push it again in the effect context below.
9923639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    Drop(key == NULL ? 1 : 2);
9924639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    environment()->SetExpressionStackAt(0, input);
9925639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    CHECK_ALIVE(BuildStoreForEffect(
9926639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org        expr, prop, expr->id(), expr->AssignmentId(), object, key, after));
9927639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    return ast_context()->ReturnValue(Pop());
9928a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
9929c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
9930639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  environment()->SetExpressionStackAt(0, after);
9931639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  return BuildStore(expr, prop, expr->id(), expr->AssignmentId());
9932a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
9933a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9934a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
99352e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgHInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt(
9936a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    HValue* string,
9937a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    HValue* index) {
99382e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  if (string->IsConstant() && index->IsConstant()) {
99392e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    HConstant* c_string = HConstant::cast(string);
99402e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    HConstant* c_index = HConstant::cast(index);
99412e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    if (c_string->HasStringValue() && c_index->HasNumberValue()) {
99422e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      int32_t i = c_index->NumberValueAsInteger32();
99432e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      Handle<String> s = c_string->StringValue();
99442e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      if (i < 0 || i >= s->length()) {
9945d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        return New<HConstant>(OS::nan_value());
99462e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      }
9947d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      return New<HConstant>(s->Get(i));
99482e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    }
99492e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
99500f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  string = BuildCheckString(string);
99510f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  index = Add<HBoundsCheck>(index, AddLoadStringLength(string));
99520f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  return New<HStringCharCodeAt>(string, index);
99530a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org}
99540a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
9955e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
9956528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org// Checks if the given shift amounts have following forms:
9957528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org// (N1) and (N2) with N1 + N2 = 32; (sa) and (32 - sa).
9958e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgstatic bool ShiftAmountsAllowReplaceByRotate(HValue* sa,
9959e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org                                             HValue* const32_minus_sa) {
9960528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (sa->IsConstant() && const32_minus_sa->IsConstant()) {
9961528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    const HConstant* c1 = HConstant::cast(sa);
9962528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    const HConstant* c2 = HConstant::cast(const32_minus_sa);
9963528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    return c1->HasInteger32Value() && c2->HasInteger32Value() &&
9964528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        (c1->Integer32Value() + c2->Integer32Value() == 32);
9965528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
9966e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (!const32_minus_sa->IsSub()) return false;
9967e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  HSub* sub = HSub::cast(const32_minus_sa);
9968381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org  return sub->left()->EqualsInteger32Constant(32) && sub->right() == sa;
9969e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org}
9970e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
9971e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
9972e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org// Checks if the left and the right are shift instructions with the oposite
9973e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org// directions that can be replaced by one rotate right instruction or not.
9974e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org// Returns the operand and the shift amount for the rotate instruction in the
9975e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org// former case.
9976528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgbool HGraphBuilder::MatchRotateRight(HValue* left,
9977528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                     HValue* right,
9978528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                     HValue** operand,
9979528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                     HValue** shift_amount) {
9980e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  HShl* shl;
9981e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  HShr* shr;
9982e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (left->IsShl() && right->IsShr()) {
9983e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    shl = HShl::cast(left);
9984e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    shr = HShr::cast(right);
9985e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  } else if (left->IsShr() && right->IsShl()) {
9986e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    shl = HShl::cast(right);
9987e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    shr = HShr::cast(left);
9988e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  } else {
9989e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    return false;
9990e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  }
99916bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org  if (shl->left() != shr->left()) return false;
9992e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
9993e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (!ShiftAmountsAllowReplaceByRotate(shl->right(), shr->right()) &&
9994e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      !ShiftAmountsAllowReplaceByRotate(shr->right(), shl->right())) {
9995e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    return false;
9996e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  }
9997e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  *operand= shr->left();
9998e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  *shift_amount = shr->right();
9999e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  return true;
10000e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org}
10001e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
10002e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
100034e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.orgbool CanBeZero(HValue* right) {
10004e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (right->IsConstant()) {
10005e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    HConstant* right_const = HConstant::cast(right);
10006e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    if (right_const->HasInteger32Value() &&
10007e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org       (right_const->Integer32Value() & 0x1f) != 0) {
10008e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      return false;
10009e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    }
10010e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  }
10011e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  return true;
10012e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org}
10013e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
100140a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
10015528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgHValue* HGraphBuilder::EnforceNumberType(HValue* number,
100166d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org                                         Type* expected) {
100174452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org  if (expected->Is(Type::SignedSmall())) {
10018ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    return AddUncasted<HForceRepresentation>(number, Representation::Smi());
10019ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  }
10020ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  if (expected->Is(Type::Signed32())) {
10021ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    return AddUncasted<HForceRepresentation>(number,
10022ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org                                             Representation::Integer32());
10023ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  }
10024ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  return number;
10025528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org}
10026528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
10027528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
100286d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.orgHValue* HGraphBuilder::TruncateToNumber(HValue* value, Type** expected) {
10029c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if (value->IsConstant()) {
10030c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    HConstant* constant = HConstant::cast(value);
10031c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    Maybe<HConstant*> number = constant->CopyToTruncatedNumber(zone());
10032c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    if (number.has_value) {
100336d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org      *expected = Type::Number(zone());
10034c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org      return AddInstruction(number.value);
10035c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    }
10036c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  }
10037c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
10038528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // We put temporary values on the stack, which don't correspond to anything
10039528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // in baseline code. Since nothing is observable we avoid recording those
10040528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // pushes with a NoObservableSideEffectsScope.
10041528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  NoObservableSideEffectsScope no_effects(this);
10042528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
100436d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  Type* expected_type = *expected;
10044528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
10045528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // Separate the number type from the rest.
100466d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  Type* expected_obj =
100476d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org      Type::Intersect(expected_type, Type::NonNumber(zone()), zone());
100486d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  Type* expected_number =
100496d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org      Type::Intersect(expected_type, Type::Number(zone()), zone());
10050528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
10051528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // We expect to get a number.
10052528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // (We need to check first, since Type::None->Is(Type::Any()) == true.
10053528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (expected_obj->Is(Type::None())) {
100546d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org    ASSERT(!expected_number->Is(Type::None(zone())));
10055528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    return value;
10056528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
10057528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
100586d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  if (expected_obj->Is(Type::Undefined(zone()))) {
10059528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // This is already done by HChange.
100607e6132b924829c353864933f29124419916db550machenbach@chromium.org    *expected = Type::Union(expected_number, Type::Number(zone()), zone());
10061528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    return value;
10062528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
10063528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
10064c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  return value;
10065c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
10066c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
10067c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
100687ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.orgHValue* HOptimizedGraphBuilder::BuildBinaryOperation(
10069a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    BinaryOperation* expr,
10070a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    HValue* left,
1007125530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org    HValue* right,
1007225530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org    PushBeforeSimulateBehavior push_sim_result) {
100736d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  Type* left_type = expr->left()->bounds().lower;
100746d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  Type* right_type = expr->right()->bounds().lower;
100756d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  Type* result_type = expr->bounds().lower;
100761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Maybe<int> fixed_right_arg = expr->fixed_right_arg();
100770f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  Handle<AllocationSite> allocation_site = expr->allocation_site();
100780f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
10079d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  HAllocationMode allocation_mode;
10080d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  if (FLAG_allocation_site_pretenuring && !allocation_site.is_null()) {
10081d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    allocation_mode = HAllocationMode(allocation_site);
10082d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  }
10083528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
100847ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  HValue* result = HGraphBuilder::BuildBinaryOperation(
100850f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      expr->op(), left, right, left_type, right_type, result_type,
100860f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      fixed_right_arg, allocation_mode);
100877ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  // Add a simulate after instructions with observable side effects, and
100887ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  // after phis, which are the result of BuildBinaryOperation when we
100897ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  // inlined some complex subgraph.
100907ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  if (result->HasObservableSideEffects() || result->IsPhi()) {
10091f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (push_sim_result == PUSH_BEFORE_SIMULATE) {
10092052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org      Push(result);
10093bfd1d202fb7cd6d54d956414bad9f75a995d0f65machenbach@chromium.org      Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
10094052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org      Drop(1);
10095f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    } else {
10096f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
1009725530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org    }
100987ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  }
100997ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  return result;
10100528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org}
10101528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
10102528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
101037ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.orgHValue* HGraphBuilder::BuildBinaryOperation(
10104528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Token::Value op,
10105528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    HValue* left,
10106528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    HValue* right,
101076d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org    Type* left_type,
101086d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org    Type* right_type,
101096d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org    Type* result_type,
101100f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    Maybe<int> fixed_right_arg,
101110f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    HAllocationMode allocation_mode) {
10112528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
10113e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  Representation left_rep = Representation::FromType(left_type);
10114e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  Representation right_rep = Representation::FromType(right_type);
10115e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
10116528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  bool maybe_string_add = op == Token::ADD &&
10117528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                          (left_type->Maybe(Type::String()) ||
10118528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                           right_type->Maybe(Type::String()));
10119c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
10120b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  if (left_type->Is(Type::None())) {
101213d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation",
10122594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                     Deoptimizer::SOFT);
10123528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // TODO(rossberg): we should be able to get rid of non-continuous
10124528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // defaults.
101256d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org    left_type = Type::Any(zone());
10126528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  } else {
10127528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    if (!maybe_string_add) left = TruncateToNumber(left, &left_type);
10128528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    left_rep = Representation::FromType(left_type);
10129b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  }
10130528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
10131b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  if (right_type->Is(Type::None())) {
101323d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    Add<HDeoptimize>("Insufficient type feedback for RHS of binary operation",
10133594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                     Deoptimizer::SOFT);
101346d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org    right_type = Type::Any(zone());
10135528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  } else {
10136528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    if (!maybe_string_add) right = TruncateToNumber(right, &right_type);
10137528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    right_rep = Representation::FromType(right_type);
10138e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  }
10139528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
10140e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org  // Special case for string addition here.
10141e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org  if (op == Token::ADD &&
10142e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      (left_type->Is(Type::String()) || right_type->Is(Type::String()))) {
10143b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    // Validate type feedback for left argument.
10144e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org    if (left_type->Is(Type::String())) {
1014590dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org      left = BuildCheckString(left);
10146b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    }
10147b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
10148b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    // Validate type feedback for right argument.
10149b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    if (right_type->Is(Type::String())) {
1015090dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org      right = BuildCheckString(right);
10151b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    }
10152b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
10153b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    // Convert left argument as necessary.
10154b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    if (left_type->Is(Type::Number())) {
10155b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      ASSERT(right_type->Is(Type::String()));
10156e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      left = BuildNumberToString(left, left_type);
10157b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    } else if (!left_type->Is(Type::String())) {
10158e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      ASSERT(right_type->Is(Type::String()));
10159e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_RIGHT);
101608d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      Add<HPushArguments>(left, right);
101617ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org      return AddUncasted<HInvokeFunction>(function, 2);
10162e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org    }
10163e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org
10164b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    // Convert right argument as necessary.
10165b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    if (right_type->Is(Type::Number())) {
10166b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      ASSERT(left_type->Is(Type::String()));
10167e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      right = BuildNumberToString(right, right_type);
10168b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    } else if (!right_type->Is(Type::String())) {
10169e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      ASSERT(left_type->Is(Type::String()));
10170e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT);
101718d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      Add<HPushArguments>(left, right);
101727ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org      return AddUncasted<HInvokeFunction>(function, 2);
10173e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org    }
10174e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org
10175bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org    // Fast path for empty constant strings.
10176bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org    if (left->IsConstant() &&
10177bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org        HConstant::cast(left)->HasStringValue() &&
10178bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org        HConstant::cast(left)->StringValue()->length() == 0) {
10179bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org      return right;
10180bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org    }
10181bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org    if (right->IsConstant() &&
10182bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org        HConstant::cast(right)->HasStringValue() &&
10183bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org        HConstant::cast(right)->StringValue()->length() == 0) {
10184bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org      return left;
101850f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    }
101860f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
101870f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    // Register the dependent code with the allocation site.
101880f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    if (!allocation_mode.feedback_site().is_null()) {
101890f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      ASSERT(!graph()->info()->IsStub());
101904ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org      Handle<AllocationSite> site(allocation_mode.feedback_site());
101914ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org      AllocationSite::AddDependentCompilationInfo(
101924ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org          site, AllocationSite::TENURING, top_info());
101930f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    }
101940f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
10195bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org    // Inline the string addition into the stub when creating allocation
10196bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org    // mementos to gather allocation site feedback, or if we can statically
10197bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org    // infer that we're going to create a cons string.
10198bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org    if ((graph()->info()->IsStub() &&
10199bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org         allocation_mode.CreateAllocationMementos()) ||
10200bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org        (left->IsConstant() &&
10201bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org         HConstant::cast(left)->HasStringValue() &&
10202bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org         HConstant::cast(left)->StringValue()->length() + 1 >=
10203bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org           ConsString::kMinLength) ||
10204bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org        (right->IsConstant() &&
10205bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org         HConstant::cast(right)->HasStringValue() &&
10206bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org         HConstant::cast(right)->StringValue()->length() + 1 >=
10207bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org           ConsString::kMinLength)) {
10208bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org      return BuildStringAdd(left, right, allocation_mode);
102090f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    }
102100f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
102110f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    // Fallback to using the string add stub.
102120f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org    return AddUncasted<HStringAdd>(
102130f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org        left, right, allocation_mode.GetPretenureMode(),
102140f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org        STRING_ADD_CHECK_NONE, allocation_mode.feedback_site());
10215e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org  }
10216e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org
10217f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  if (graph()->info()->IsStub()) {
1021825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    left = EnforceNumberType(left, left_type);
1021925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    right = EnforceNumberType(right, right_type);
1022025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  }
1022125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
10222528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Representation result_rep = Representation::FromType(result_type);
10223528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
1022425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) ||
1022525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org                          (right_rep.IsTagged() && !right_rep.IsSmi());
10226528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
10227e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  HInstruction* instr = NULL;
1022825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  // Only the stub is allowed to call into the runtime, since otherwise we would
1022925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  // inline several instructions (including the two pushes) for every tagged
1023025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  // operation in optimized code, which is more expensive, than a stub call.
10231f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  if (graph()->info()->IsStub() && is_non_primitive) {
1023225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    HValue* function = AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op));
102338d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    Add<HPushArguments>(left, right);
102347ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org    instr = AddUncasted<HInvokeFunction>(function, 2);
1023525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  } else {
1023625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    switch (op) {
1023725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      case Token::ADD:
102387ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org        instr = AddUncasted<HAdd>(left, right);
1023925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        break;
1024025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      case Token::SUB:
102417ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org        instr = AddUncasted<HSub>(left, right);
1024225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        break;
1024325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      case Token::MUL:
102447ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org        instr = AddUncasted<HMul>(left, right);
1024525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        break;
102467ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org      case Token::MOD: {
10247381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org        if (fixed_right_arg.has_value &&
10248381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org            !right->EqualsInteger32Constant(fixed_right_arg.value)) {
10249381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org          HConstant* fixed_right = Add<HConstant>(
10250381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org              static_cast<int>(fixed_right_arg.value));
10251381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org          IfBuilder if_same(this);
10252381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org          if_same.If<HCompareNumericAndBranch>(right, fixed_right, Token::EQ);
10253381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org          if_same.Then();
10254381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org          if_same.ElseDeopt("Unexpected RHS of binary operation");
10255381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org          right = fixed_right;
102567ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org        }
102577ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org        instr = AddUncasted<HMod>(left, right);
1025825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        break;
102597ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org      }
1026025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      case Token::DIV:
102617ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org        instr = AddUncasted<HDiv>(left, right);
1026225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        break;
1026325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      case Token::BIT_XOR:
1026425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      case Token::BIT_AND:
102657ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org        instr = AddUncasted<HBitwise>(op, left, right);
1026625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        break;
1026725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      case Token::BIT_OR: {
1026825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        HValue* operand, *shift_amount;
1026925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        if (left_type->Is(Type::Signed32()) &&
1027025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org            right_type->Is(Type::Signed32()) &&
1027125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org            MatchRotateRight(left, right, &operand, &shift_amount)) {
102727ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org          instr = AddUncasted<HRor>(operand, shift_amount);
1027325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        } else {
102747ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org          instr = AddUncasted<HBitwise>(op, left, right);
1027525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        }
1027625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        break;
10277e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      }
1027825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      case Token::SAR:
102797ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org        instr = AddUncasted<HSar>(left, right);
1028025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        break;
1028125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      case Token::SHR:
102827ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org        instr = AddUncasted<HShr>(left, right);
1028325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        if (FLAG_opt_safe_uint32_operations && instr->IsShr() &&
1028425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org            CanBeZero(right)) {
1028525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org          graph()->RecordUint32Instruction(instr);
1028625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        }
1028725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        break;
1028825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      case Token::SHL:
102897ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org        instr = AddUncasted<HShl>(left, right);
1029025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        break;
1029125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      default:
1029225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        UNREACHABLE();
10293e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    }
10294e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  }
10295e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
10296fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  if (instr->IsBinaryOperation()) {
10297fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    HBinaryOperation* binop = HBinaryOperation::cast(instr);
10298ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    binop->set_observed_input_representation(1, left_rep);
10299ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    binop->set_observed_input_representation(2, right_rep);
10300fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    binop->initialize_output_representation(result_rep);
10301f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    if (graph()->info()->IsStub()) {
1030225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      // Stub should not call into stub.
1030325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      instr->SetFlag(HValue::kCannotBeTagged);
1030425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      // And should truncate on HForceRepresentation already.
1030525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      if (left->IsForceRepresentation()) {
1030625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        left->CopyFlag(HValue::kTruncatingToSmi, instr);
1030725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        left->CopyFlag(HValue::kTruncatingToInt32, instr);
1030825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      }
1030925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      if (right->IsForceRepresentation()) {
1031025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        right->CopyFlag(HValue::kTruncatingToSmi, instr);
1031125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        right->CopyFlag(HValue::kTruncatingToInt32, instr);
1031225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      }
1031325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    }
10314a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
10315a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return instr;
10316a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
10317a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10318a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10319a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Check for the form (%_ClassOf(foo) === 'BarClass').
10320a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgstatic bool IsClassOfTest(CompareOperation* expr) {
10321a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (expr->op() != Token::EQ_STRICT) return false;
10322a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CallRuntime* call = expr->left()->AsCallRuntime();
10323a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (call == NULL) return false;
10324a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Literal* literal = expr->right()->AsLiteral();
10325a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (literal == NULL) return false;
103261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (!literal->value()->IsString()) return false;
1032759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  if (!call->name()->IsOneByteEqualTo(STATIC_ASCII_VECTOR("_ClassOf"))) {
1032859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    return false;
1032959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  }
10330a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(call->arguments()->length() == 1);
10331a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return true;
10332a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
10333a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10334a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10335a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) {
10336160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
10337160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
10338160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
1033983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  switch (expr->op()) {
10340d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com    case Token::COMMA:
10341d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com      return VisitComma(expr);
10342d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com    case Token::OR:
10343d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com    case Token::AND:
10344d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com      return VisitLogicalExpression(expr);
10345d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com    default:
10346d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com      return VisitArithmeticExpression(expr);
1034783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
1034883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
103495f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
103505f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
10351a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitComma(BinaryOperation* expr) {
1035283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  CHECK_ALIVE(VisitForEffect(expr->left()));
1035383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Visit the right subexpression in the same AST context as the entire
1035483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // expression.
1035583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Visit(expr->right());
1035683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
103575f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
103588f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
10359a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) {
10360d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  bool is_logical_and = expr->op() == Token::AND;
1036183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (ast_context()->IsTest()) {
1036283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    TestContext* context = TestContext::cast(ast_context());
1036383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // Translate left subexpression.
1036483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    HBasicBlock* eval_right = graph()->CreateBasicBlock();
1036583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    if (is_logical_and) {
1036683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      CHECK_BAILOUT(VisitForControl(expr->left(),
1036783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                    eval_right,
1036883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                    context->if_false()));
1036983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    } else {
1037083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      CHECK_BAILOUT(VisitForControl(expr->left(),
1037183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                    context->if_true(),
1037283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                    eval_right));
1037383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    }
1037483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
1037583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // Translate right subexpression by visiting it in the same AST
1037683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // context as the entire expression.
1037783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    if (eval_right->HasPredecessor()) {
1037883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      eval_right->SetJoinId(expr->RightId());
103798f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      set_current_block(eval_right);
1038083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Visit(expr->right());
1038183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    }
103828f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
1038383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  } else if (ast_context()->IsValue()) {
1038483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    CHECK_ALIVE(VisitForValue(expr->left()));
1038583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    ASSERT(current_block() != NULL);
103862e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    HValue* left_value = Top();
103872e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
103886f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org    // Short-circuit left values that always evaluate to the same boolean value.
103896f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org    if (expr->left()->ToBooleanIsTrue() || expr->left()->ToBooleanIsFalse()) {
103906f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org      // l (evals true)  && r -> r
103916f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org      // l (evals true)  || r -> l
103926f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org      // l (evals false) && r -> l
103936f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org      // l (evals false) || r -> r
103946f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org      if (is_logical_and == expr->left()->ToBooleanIsTrue()) {
103956f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org        Drop(1);
10396bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org        CHECK_ALIVE(VisitForValue(expr->right()));
103972e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      }
103982e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      return ast_context()->ReturnValue(Pop());
103992e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    }
1040083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
1040183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // We need an extra block to maintain edge-split form.
1040283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    HBasicBlock* empty_block = graph()->CreateBasicBlock();
1040383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    HBasicBlock* eval_right = graph()->CreateBasicBlock();
10404c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    ToBooleanStub::Types expected(expr->left()->to_boolean_types());
104054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    HBranch* test = is_logical_and
10406528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        ? New<HBranch>(left_value, expected, eval_right, empty_block)
10407528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        : New<HBranch>(left_value, expected, empty_block, eval_right);
1040871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    FinishCurrentBlock(test);
1040983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
1041083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    set_current_block(eval_right);
1041183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Drop(1);  // Value of the left subexpression.
1041283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    CHECK_BAILOUT(VisitForValue(expr->right()));
1041383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
1041483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    HBasicBlock* join_block =
1041583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      CreateJoin(empty_block, current_block(), expr->id());
1041683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    set_current_block(join_block);
104174f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    return ast_context()->ReturnValue(Pop());
104188f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
1041983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  } else {
1042083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    ASSERT(ast_context()->IsEffect());
1042183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // In an effect context, we don't need the value of the left subexpression,
1042283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // only its control flow and side effects.  We need an extra block to
1042383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // maintain edge-split form.
1042483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    HBasicBlock* empty_block = graph()->CreateBasicBlock();
1042583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    HBasicBlock* right_block = graph()->CreateBasicBlock();
1042683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    if (is_logical_and) {
1042783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      CHECK_BAILOUT(VisitForControl(expr->left(), right_block, empty_block));
104283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    } else {
1042983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      CHECK_BAILOUT(VisitForControl(expr->left(), empty_block, right_block));
1043083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    }
10431160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org
1043283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // TODO(kmillikin): Find a way to fix this.  It's ugly that there are
1043383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // actually two empty blocks (one here and one inserted by
1043483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // TestContext::BuildBranch, and that they both have an HSimulate though the
1043583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // second one is not a merge node, and that we really have no good AST ID to
1043683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // put on that first HSimulate.
10437160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org
1043883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    if (empty_block->HasPredecessor()) {
1043983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      empty_block->SetJoinId(expr->id());
1044083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    } else {
1044183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      empty_block = NULL;
104425f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org    }
10443a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1044483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    if (right_block->HasPredecessor()) {
1044583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      right_block->SetJoinId(expr->RightId());
1044683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      set_current_block(right_block);
1044783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      CHECK_BAILOUT(VisitForEffect(expr->right()));
1044883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      right_block = current_block();
1044983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    } else {
1045083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      right_block = NULL;
1045183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    }
10452a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1045383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    HBasicBlock* join_block =
1045483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      CreateJoin(empty_block, right_block, expr->id());
1045583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    set_current_block(join_block);
1045683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // We did not materialize any value in the predecessor environments,
1045783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // so there is no need to handle it here.
10458a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
10459a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
10460a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10461a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10462a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) {
1046383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  CHECK_ALIVE(VisitForValue(expr->left()));
1046483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  CHECK_ALIVE(VisitForValue(expr->right()));
10465af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  SetSourcePosition(expr->position());
1046683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  HValue* right = Pop();
1046783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  HValue* left = Pop();
1046825530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org  HValue* result =
1046925530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org      BuildBinaryOperation(expr, left, right,
1047025530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org          ast_context()->IsEffect() ? NO_PUSH_BEFORE_SIMULATE
1047125530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org                                    : PUSH_BEFORE_SIMULATE);
10472f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (FLAG_hydrogen_track_positions && result->IsBinaryOperation()) {
104737ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org    HBinaryOperation::cast(result)->SetOperandPositions(
10474f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        zone(),
10475f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        ScriptPositionToSourcePosition(expr->left()->position()),
10476f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        ScriptPositionToSourcePosition(expr->right()->position()));
10477af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  }
104787ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  return ast_context()->ReturnValue(result);
1047983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
1048083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
1048183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
10482a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr,
1048396a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org                                                        Expression* sub_expr,
10484a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                                        Handle<String> check) {
1048596a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org  CHECK_ALIVE(VisitForTypeOf(sub_expr));
10486af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  SetSourcePosition(expr->position());
1048796a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org  HValue* value = Pop();
10488db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org  HTypeofIsAndBranch* instr = New<HTypeofIsAndBranch>(value, check);
10489c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return ast_context()->ReturnControl(instr, expr->id());
1049004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org}
1049104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org
1049204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org
10493639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.orgstatic bool IsLiteralCompareBool(Isolate* isolate,
10494639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org                                 HValue* left,
104952c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org                                 Token::Value op,
104962c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org                                 HValue* right) {
104972c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  return op == Token::EQ_STRICT &&
10498639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org      ((left->IsConstant() &&
10499639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org          HConstant::cast(left)->handle(isolate)->IsBoolean()) ||
10500639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org       (right->IsConstant() &&
10501639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org           HConstant::cast(right)->handle(isolate)->IsBoolean()));
105022c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org}
105032c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
105042c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org
10505a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
10506160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
10507160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
10508160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
1050996a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org
10510f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position());
1051171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org
1051296a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org  // Check for a few fast cases. The AST visiting behavior must be in sync
1051396a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org  // with the full codegen: We don't push both left and right values onto
1051496a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org  // the expression stack when one side is a special-case literal.
1051596a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org  Expression* sub_expr = NULL;
1051696a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org  Handle<String> check;
1051796a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org  if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) {
1051896a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org    return HandleLiteralCompareTypeof(expr, sub_expr, check);
1051996a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org  }
1052096a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org  if (expr->IsLiteralCompareUndefined(&sub_expr, isolate())) {
1052196a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org    return HandleLiteralCompareNil(expr, sub_expr, kUndefinedValue);
1052296a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org  }
1052396a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org  if (expr->IsLiteralCompareNull(&sub_expr)) {
1052496a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org    return HandleLiteralCompareNil(expr, sub_expr, kNullValue);
1052596a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org  }
1052696a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org
10527a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (IsClassOfTest(expr)) {
10528a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    CallRuntime* call = expr->left()->AsCallRuntime();
105294f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    ASSERT(call->arguments()->length() == 1);
10530160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org    CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
10531a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    HValue* value = Pop();
10532a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Literal* literal = expr->right()->AsLiteral();
105331510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Handle<String> rhs = Handle<String>::cast(literal->value());
10534db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org    HClassOfTestAndBranch* instr = New<HClassOfTestAndBranch>(value, rhs);
105354f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    return ast_context()->ReturnControl(instr, expr->id());
10536a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
10537a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
105386d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  Type* left_type = expr->left()->bounds().lower;
105396d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  Type* right_type = expr->right()->bounds().lower;
105406d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  Type* combined_type = expr->combined_type();
10541e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
10542160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  CHECK_ALIVE(VisitForValue(expr->left()));
10543160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  CHECK_ALIVE(VisitForValue(expr->right()));
10544a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10545f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (FLAG_hydrogen_track_positions) SetSourcePosition(expr->position());
10546af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
10547a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HValue* right = Pop();
10548a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HValue* left = Pop();
10549a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Token::Value op = expr->op();
10550a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10551639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  if (IsLiteralCompareBool(isolate(), left, op, right)) {
105522c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org    HCompareObjectEqAndBranch* result =
10553d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        New<HCompareObjectEqAndBranch>(left, right);
105542c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org    return ast_context()->ReturnControl(result, expr->id());
105552c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  }
10556394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
10557a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (op == Token::INSTANCEOF) {
10558d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org    // Check to see if the rhs of the instanceof is a global function not
10559d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org    // residing in new space. If it is we assume that the function will stay the
10560d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org    // same.
10561d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org    Handle<JSFunction> target = Handle<JSFunction>::null();
10562486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    VariableProxy* proxy = expr->right()->AsVariableProxy();
10563486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    bool global_function = (proxy != NULL) && proxy->var()->IsUnallocated();
10564d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org    if (global_function &&
1056541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org        current_info()->has_global_object() &&
1056641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org        !current_info()->global_object()->IsAccessCheckNeeded()) {
10567486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org      Handle<String> name = proxy->name();
1056841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      Handle<GlobalObject> global(current_info()->global_object());
10569394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      LookupResult lookup(isolate());
105703484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      global->Lookup(name, &lookup);
10571de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org      if (lookup.IsNormal() && lookup.GetValue()->IsJSFunction()) {
10572d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org        Handle<JSFunction> candidate(JSFunction::cast(lookup.GetValue()));
10573d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org        // If the function is in new space we assume it's more likely to
10574d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org        // change and thus prefer the general IC code.
10575ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        if (!isolate()->heap()->InNewSpace(*candidate)) {
10576d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org          target = candidate;
10577d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org        }
10578d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org      }
10579d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org    }
10580d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
10581d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org    // If the target is not null we have found a known global function that is
10582d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org    // assumed to stay the same for this instanceof.
10583d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org    if (target.is_null()) {
10584db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org      HInstanceOf* result = New<HInstanceOf>(left, right);
105854f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      return ast_context()->ReturnInstruction(result, expr->id());
10586d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org    } else {
105871f410f9a9c4fbd4270749af64b477df87b753158mstarzinger@chromium.org      Add<HCheckValue>(right, target);
105884f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      HInstanceOfKnownGlobal* result =
105898e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org        New<HInstanceOfKnownGlobal>(left, target);
105904f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      return ast_context()->ReturnInstruction(result, expr->id());
10591d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org    }
10592c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org
10593c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    // Code below assumes that we don't fall through.
10594c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    UNREACHABLE();
10595a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else if (op == Token::IN) {
10596d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    HValue* function = AddLoadJSBuiltin(Builtins::IN);
105978d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    Add<HPushArguments>(left, right);
10598bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    // TODO(olivf) InvokeFunction produces a check for the parameter count,
10599bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    // even though we are certain to pass the correct number of arguments here.
106008e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org    HInstruction* result = New<HInvokeFunction>(function, 2);
106014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    return ast_context()->ReturnInstruction(result, expr->id());
10602c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  }
10603c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org
10604f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  PushBeforeSimulateBehavior push_behavior =
10605f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    ast_context()->IsEffect() ? NO_PUSH_BEFORE_SIMULATE
10606f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                              : PUSH_BEFORE_SIMULATE;
106074f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  HControlInstruction* compare = BuildCompareInstruction(
106084f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      op, left, right, left_type, right_type, combined_type,
10609f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      ScriptPositionToSourcePosition(expr->left()->position()),
10610f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      ScriptPositionToSourcePosition(expr->right()->position()),
10611f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      push_behavior, expr->id());
106124f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  if (compare == NULL) return;  // Bailed out.
106134f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  return ast_context()->ReturnControl(compare, expr->id());
106144f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org}
106154f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org
106164f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org
106174f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.orgHControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction(
106184f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org    Token::Value op,
106194f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org    HValue* left,
106204f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org    HValue* right,
106216d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org    Type* left_type,
106226d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org    Type* right_type,
106236d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org    Type* combined_type,
10624f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    HSourcePosition left_position,
10625f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    HSourcePosition right_position,
10626f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    PushBeforeSimulateBehavior push_sim_result,
106274f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org    BailoutId bailout_id) {
1062871ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org  // Cases handled below depend on collected type feedback. They should
1062971ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org  // soft deoptimize when there is no type feedback.
1063071ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org  if (combined_type->Is(Type::None())) {
1063171ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org    Add<HDeoptimize>("Insufficient type feedback for combined type "
1063271ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org                     "of binary operation",
1063371ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org                     Deoptimizer::SOFT);
106346d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org    combined_type = left_type = right_type = Type::Any(zone());
1063571ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org  }
1063671ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org
106374f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  Representation left_rep = Representation::FromType(left_type);
106384f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  Representation right_rep = Representation::FromType(right_type);
106394f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  Representation combined_rep = Representation::FromType(combined_type);
106404f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org
10641c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  if (combined_type->Is(Type::Receiver())) {
106424f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org    if (Token::IsEqualityOp(op)) {
106432ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      // HCompareObjectEqAndBranch can only deal with object, so
106442ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      // exclude numbers.
106452ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      if ((left->IsConstant() &&
106462ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org           HConstant::cast(left)->HasNumberValue()) ||
106472ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org          (right->IsConstant() &&
106482ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org           HConstant::cast(right)->HasNumberValue())) {
106492ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        Add<HDeoptimize>("Type mismatch between feedback and constant",
106502ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                         Deoptimizer::SOFT);
106512ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        // The caller expects a branch instruction, so make it happy.
106522ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        return New<HBranch>(graph()->GetConstantTrue());
106532ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      }
106544f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      // Can we get away with map check and not instance type check?
1065571ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org      HValue* operand_to_check =
1065671ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org          left->block()->block_id() < right->block()->block_id() ? left : right;
106574f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      if (combined_type->IsClass()) {
106589fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org        Handle<Map> map = combined_type->AsClass()->Map();
1065971ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org        AddCheckMap(operand_to_check, map);
106604f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org        HCompareObjectEqAndBranch* result =
106614f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org            New<HCompareObjectEqAndBranch>(left, right);
10662f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        if (FLAG_hydrogen_track_positions) {
106634f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org          result->set_operand_position(zone(), 0, left_position);
106644f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org          result->set_operand_position(zone(), 1, right_position);
1066564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org        }
106664f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org        return result;
106674f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      } else {
1066871ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org        BuildCheckHeapObject(operand_to_check);
1066971ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org        Add<HCheckInstanceType>(operand_to_check,
1067071ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org                                HCheckInstanceType::IS_SPEC_OBJECT);
106714f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org        HCompareObjectEqAndBranch* result =
106724f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org            New<HCompareObjectEqAndBranch>(left, right);
106734f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org        return result;
10674a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
106754f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org    } else {
106764f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      Bailout(kUnsupportedNonPrimitiveCompare);
106774f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      return NULL;
10678a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
106791510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  } else if (combined_type->Is(Type::InternalizedString()) &&
106804a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org             Token::IsEqualityOp(op)) {
106815b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    // If we have a constant argument, it should be consistent with the type
106825b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    // feedback (otherwise we fail assertions in HCompareObjectEqAndBranch).
106835b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    if ((left->IsConstant() &&
106845b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org         !HConstant::cast(left)->HasInternalizedStringValue()) ||
106855b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org        (right->IsConstant() &&
106865b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org         !HConstant::cast(right)->HasInternalizedStringValue())) {
106875b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      Add<HDeoptimize>("Type mismatch between feedback and constant",
106885b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org                       Deoptimizer::SOFT);
106895b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      // The caller expects a branch instruction, so make it happy.
106905b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org      return New<HBranch>(graph()->GetConstantTrue());
106915b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org    }
106921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    BuildCheckHeapObject(left);
10693c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    Add<HCheckInstanceType>(left, HCheckInstanceType::IS_INTERNALIZED_STRING);
106941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    BuildCheckHeapObject(right);
10695c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    Add<HCheckInstanceType>(right, HCheckInstanceType::IS_INTERNALIZED_STRING);
106964f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    HCompareObjectEqAndBranch* result =
10697528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        New<HCompareObjectEqAndBranch>(left, right);
106984f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org    return result;
10699d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  } else if (combined_type->Is(Type::String())) {
10700d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    BuildCheckHeapObject(left);
10701c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    Add<HCheckInstanceType>(left, HCheckInstanceType::IS_STRING);
10702d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    BuildCheckHeapObject(right);
10703c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    Add<HCheckInstanceType>(right, HCheckInstanceType::IS_STRING);
10704d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    HStringCompareAndBranch* result =
10705d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org        New<HStringCompareAndBranch>(left, right, op);
107064f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org    return result;
10707a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  } else {
10708fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    if (combined_rep.IsTagged() || combined_rep.IsNone()) {
107094f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      HCompareGeneric* result = Add<HCompareGeneric>(left, right, op);
10710ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      result->set_observed_input_representation(1, left_rep);
10711ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      result->set_observed_input_representation(2, right_rep);
107124f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      if (result->HasObservableSideEffects()) {
10713f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        if (push_sim_result == PUSH_BEFORE_SIMULATE) {
10714f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          Push(result);
10715f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          AddSimulate(bailout_id, REMOVABLE_SIMULATE);
10716f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          Drop(1);
10717f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        } else {
10718f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          AddSimulate(bailout_id, REMOVABLE_SIMULATE);
10719f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        }
107204f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      }
107214f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      // TODO(jkummerow): Can we make this more efficient?
107224f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      HBranch* branch = New<HBranch>(result);
107234f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      return branch;
107244f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    } else {
10725e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org      HCompareNumericAndBranch* result =
10726528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org          New<HCompareNumericAndBranch>(left, right, op);
10727fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      result->set_observed_input_representation(left_rep, right_rep);
10728f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      if (FLAG_hydrogen_track_positions) {
107294f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org        result->SetOperandPositions(zone(), left_position, right_position);
10730af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org      }
107314f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org      return result;
107324f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    }
10733a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
10734a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
10735a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10736a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10737a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr,
1073896a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org                                                     Expression* sub_expr,
10739a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                                                     NilValue nil) {
10740160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
10741160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
10742160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
1074341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  ASSERT(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT);
10744f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position());
1074596a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org  CHECK_ALIVE(VisitForValue(sub_expr));
1074696a3c512c0c7fd9e0e1d6bb0a965a3fd051705eajkummerow@chromium.org  HValue* value = Pop();
10747837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org  if (expr->op() == Token::EQ_STRICT) {
10748ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org    HConstant* nil_constant = nil == kNullValue
10749ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org        ? graph()->GetConstantNull()
10750ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org        : graph()->GetConstantUndefined();
10751ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org    HCompareObjectEqAndBranch* instr =
10752ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org        New<HCompareObjectEqAndBranch>(value, nil_constant);
10753ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org    return ast_context()->ReturnControl(instr, expr->id());
10754ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org  } else {
10755ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org    ASSERT_EQ(Token::EQ, expr->op());
107566d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org    Type* type = expr->combined_type()->Is(Type::None())
107576d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org        ? Type::Any(zone()) : expr->combined_type();
10758ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org    HIfContinuation continuation;
1075971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    BuildCompareNil(value, type, &continuation);
10760837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org    return ast_context()->ReturnContinuation(&continuation, expr->id());
10761ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
10762a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
10763a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10764a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
10765a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgHInstruction* HOptimizedGraphBuilder::BuildThisFunction() {
107665a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // If we share optimized code between different closures, the
107675a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  // this-function is not a constant, except inside an inlined body.
107685a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  if (function_state()->outer() != NULL) {
10769d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      return New<HConstant>(
10770b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org          function_state()->compilation_info()->closure());
107715a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  } else {
10772db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org      return New<HThisFunction>();
107735a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  }
107745a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org}
107755a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
107765a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
10777e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgHInstruction* HOptimizedGraphBuilder::BuildFastLiteral(
10778b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    Handle<JSObject> boilerplate_object,
1077937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    AllocationSiteUsageContext* site_context) {
10780e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  NoObservableSideEffectsScope no_effects(this);
107814844ec2010ae872691d16199d0a685870c04bd9bhpayer@chromium.org  InstanceType instance_type = boilerplate_object->map()->instance_type();
107824844ec2010ae872691d16199d0a685870c04bd9bhpayer@chromium.org  ASSERT(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE);
10783fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org
107844844ec2010ae872691d16199d0a685870c04bd9bhpayer@chromium.org  HType type = instance_type == JS_ARRAY_TYPE
107854844ec2010ae872691d16199d0a685870c04bd9bhpayer@chromium.org      ? HType::JSArray() : HType::JSObject();
10786fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  HValue* object_size_constant = Add<HConstant>(
10787fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org      boilerplate_object->map()->instance_size());
10788c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org
10789d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  PretenureFlag pretenure_flag = NOT_TENURED;
10790c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org  if (FLAG_allocation_site_pretenuring) {
10791034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org    pretenure_flag = site_context->current()->GetPretenureMode();
107924ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org    Handle<AllocationSite> site(site_context->current());
107934ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org    AllocationSite::AddDependentCompilationInfo(
107944ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org        site, AllocationSite::TENURING, top_info());
10795c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org  }
10796c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org
107974844ec2010ae872691d16199d0a685870c04bd9bhpayer@chromium.org  HInstruction* object = Add<HAllocate>(object_size_constant, type,
107989f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org      pretenure_flag, instance_type, site_context->current());
10799dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
108007a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  // If allocation folding reaches Page::kMaxRegularHeapObjectSize the
108017a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  // elements array may not get folded into the object. Hence, we set the
108027a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  // elements pointer to empty fixed array and let store elimination remove
108037a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  // this store in the folding case.
108047a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  HConstant* empty_fixed_array = Add<HConstant>(
108057a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org      isolate()->factory()->empty_fixed_array());
108067a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org  Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
1080738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      empty_fixed_array);
108087a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org
10809dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  BuildEmitObjectHeader(boilerplate_object, object);
10810dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
10811fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  Handle<FixedArrayBase> elements(boilerplate_object->elements());
10812e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  int elements_size = (elements->length() > 0 &&
10813e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      elements->map() != isolate()->heap()->fixed_cow_array_map()) ?
10814e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org          elements->Size() : 0;
10815e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
108162904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  if (pretenure_flag == TENURED &&
108172904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      elements->map() == isolate()->heap()->fixed_cow_array_map() &&
108182904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      isolate()->heap()->InNewSpace(*elements)) {
108192904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    // If we would like to pretenure a fixed cow array, we must ensure that the
108202904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    // array is already in old space, otherwise we'll create too many old-to-
108212904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    // new-space pointers (overflowing the store buffer).
108222904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    elements = Handle<FixedArrayBase>(
108232904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org        isolate()->factory()->CopyAndTenureFixedCOWArray(
108242904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org            Handle<FixedArray>::cast(elements)));
108252904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org    boilerplate_object->set_elements(*elements);
108262904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  }
108272904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
10828dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  HInstruction* object_elements = NULL;
10829dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  if (elements_size > 0) {
10830dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    HValue* object_elements_size = Add<HConstant>(elements_size);
108316a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    InstanceType instance_type = boilerplate_object->HasFastDoubleElements()
108326a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org        ? FIXED_DOUBLE_ARRAY_TYPE : FIXED_ARRAY_TYPE;
108336a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    object_elements = Add<HAllocate>(
10834eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org        object_elements_size, HType::HeapObject(),
108356a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org        pretenure_flag, instance_type, site_context->current());
108361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
10837dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  BuildInitElementsInObjectHeader(boilerplate_object, object, object_elements);
10838dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
10839c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  // Copy object elements if non-COW.
10840c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  if (object_elements != NULL) {
10841b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    BuildEmitElements(boilerplate_object, elements, object_elements,
10842b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                      site_context);
10843c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  }
10844e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
10845e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Copy in-object properties.
108461510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (boilerplate_object->map()->NumberOfFields() != 0) {
10847c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org    BuildEmitInObjectProperties(boilerplate_object, object, site_context,
10848c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org                                pretenure_flag);
10849c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  }
10850dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  return object;
10851c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org}
10852c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
10853c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
10854dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgvoid HOptimizedGraphBuilder::BuildEmitObjectHeader(
10855c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    Handle<JSObject> boilerplate_object,
10856dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    HInstruction* object) {
10857c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  ASSERT(boilerplate_object->properties()->length() == 0);
10858c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
10859c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  Handle<Map> boilerplate_object_map(boilerplate_object->map());
10860dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  AddStoreMapConstant(object, boilerplate_object_map);
10861c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
10862c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  Handle<Object> properties_field =
10863c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      Handle<Object>(boilerplate_object->properties(), isolate());
10864c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  ASSERT(*properties_field == isolate()->heap()->empty_fixed_array());
108651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HInstruction* properties = Add<HConstant>(properties_field);
10866c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  HObjectAccess access = HObjectAccess::ForPropertiesPointer();
108670a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  Add<HStoreNamedField>(object, access, properties);
10868c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
10869c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  if (boilerplate_object->IsJSArray()) {
10870c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    Handle<JSArray> boilerplate_array =
10871c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org        Handle<JSArray>::cast(boilerplate_object);
10872c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    Handle<Object> length_field =
10873c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org        Handle<Object>(boilerplate_array->length(), isolate());
108741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    HInstruction* length = Add<HConstant>(length_field);
1087557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
10876c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    ASSERT(boilerplate_array->length()->IsSmi());
10877dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(
108780a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org        boilerplate_array->GetElementsKind()), length);
10879c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  }
10880dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org}
10881c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
10882dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
10883dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgvoid HOptimizedGraphBuilder::BuildInitElementsInObjectHeader(
10884dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    Handle<JSObject> boilerplate_object,
10885dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    HInstruction* object,
10886dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    HInstruction* object_elements) {
10887dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  ASSERT(boilerplate_object->properties()->length() == 0);
10888dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  if (object_elements == NULL) {
10889dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    Handle<Object> elements_field =
10890dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org        Handle<Object>(boilerplate_object->elements(), isolate());
10891dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    object_elements = Add<HConstant>(elements_field);
10892dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  }
10893dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
108940a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      object_elements);
10895c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org}
10896c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
10897c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
10898c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.orgvoid HOptimizedGraphBuilder::BuildEmitInObjectProperties(
10899c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    Handle<JSObject> boilerplate_object,
10900b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    HInstruction* object,
10901c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org    AllocationSiteUsageContext* site_context,
10902c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org    PretenureFlag pretenure_flag) {
109030a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  Handle<Map> boilerplate_map(boilerplate_object->map());
109040a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  Handle<DescriptorArray> descriptors(boilerplate_map->instance_descriptors());
109050a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  int limit = boilerplate_map->NumberOfOwnDescriptors();
1090657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
109074e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  int copied_fields = 0;
1090857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  for (int i = 0; i < limit; i++) {
1090957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    PropertyDetails details = descriptors->GetDetails(i);
1091057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    if (details.type() != FIELD) continue;
109114e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    copied_fields++;
1091257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    int index = descriptors->GetFieldIndex(i);
1091357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    int property_offset = boilerplate_object->GetInObjectPropertyOffset(index);
1091457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    Handle<Name> name(descriptors->GetKey(i));
10915e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    Handle<Object> value =
1091657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org        Handle<Object>(boilerplate_object->InObjectPropertyAt(index),
10917e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        isolate());
10918a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
10919a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    // The access for the store depends on the type of the boilerplate.
10920a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    HObjectAccess access = boilerplate_object->IsJSArray() ?
10921a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org        HObjectAccess::ForJSArrayOffset(property_offset) :
109220a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org        HObjectAccess::ForMapAndOffset(boilerplate_map, property_offset);
10923a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
10924e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (value->IsJSObject()) {
10925e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      Handle<JSObject> value_object = Handle<JSObject>::cast(value);
10926b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org      Handle<AllocationSite> current_site = site_context->EnterNewScope();
10927b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org      HInstruction* result =
10928b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org          BuildFastLiteral(value_object, site_context);
10929b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org      site_context->ExitScope(current_site, value_object);
109300a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      Add<HStoreNamedField>(object, access, result);
10931e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    } else {
1093257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      Representation representation = details.representation();
1093371ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org      HInstruction* value_instruction;
10934a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
1093557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      if (representation.IsDouble()) {
10936a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org        // Allocate a HeapNumber box and store the value into it.
10937dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org        HValue* heap_number_constant = Add<HConstant>(HeapNumber::kSize);
10938c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org        // This heap number alloc does not have a corresponding
10939b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org        // AllocationSite. That is okay because
10940b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org        // 1) it's a child object of another object with a valid allocation site
10941b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org        // 2) we can just use the mode of the parent object for pretenuring
10942dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org        HInstruction* double_box =
1094370ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org            Add<HAllocate>(heap_number_constant, HType::HeapObject(),
10944c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org                pretenure_flag, HEAP_NUMBER_TYPE);
10945a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org        AddStoreMapConstant(double_box,
10946a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org            isolate()->factory()->heap_number_map());
10947d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        Add<HStoreNamedField>(double_box, HObjectAccess::ForHeapNumberValue(),
109480a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                              Add<HConstant>(value));
1094957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org        value_instruction = double_box;
10950f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      } else if (representation.IsSmi()) {
10951f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        value_instruction = value->IsUninitialized()
10952f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org            ? graph()->GetConstant0()
10953f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org            : Add<HConstant>(value);
10954f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        // Ensure that value is stored as smi.
10955f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        access = access.WithRepresentation(representation);
1095671ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org      } else {
1095771ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org        value_instruction = Add<HConstant>(value);
1095857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      }
10959a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
109600a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      Add<HStoreNamedField>(object, access, value_instruction);
10961e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    }
10962e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
10963e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
109644e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  int inobject_properties = boilerplate_object->map()->inobject_properties();
109651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HInstruction* value_instruction =
109661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      Add<HConstant>(isolate()->factory()->one_pointer_filler_map());
109674e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  for (int i = copied_fields; i < inobject_properties; i++) {
1096856f4c2e9e396d74e916f0b3e0612bc0cbd29a281jkummerow@chromium.org    ASSERT(boilerplate_object->IsJSObject());
1096956f4c2e9e396d74e916f0b3e0612bc0cbd29a281jkummerow@chromium.org    int property_offset = boilerplate_object->GetInObjectPropertyOffset(i);
109700a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    HObjectAccess access =
109710a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org        HObjectAccess::ForMapAndOffset(boilerplate_map, property_offset);
109720a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    Add<HStoreNamedField>(object, access, value_instruction);
109734e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
10974e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
10975e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
10976e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
10977c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.orgvoid HOptimizedGraphBuilder::BuildEmitElements(
10978dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    Handle<JSObject> boilerplate_object,
10979c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    Handle<FixedArrayBase> elements,
10980b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    HValue* object_elements,
1098137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    AllocationSiteUsageContext* site_context) {
10982dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  ElementsKind kind = boilerplate_object->map()->elements_kind();
10983c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  int elements_length = elements->length();
109841510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HValue* object_elements_length = Add<HConstant>(elements_length);
10985c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  BuildInitializeElementsHeader(object_elements, kind, object_elements_length);
10986c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
10987c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  // Copy elements backing store content.
10988c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  if (elements->IsFixedDoubleArray()) {
10989c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    BuildEmitFixedDoubleArray(elements, kind, object_elements);
10990c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  } else if (elements->IsFixedArray()) {
10991b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    BuildEmitFixedArray(elements, kind, object_elements,
10992b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                        site_context);
10993e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  } else {
10994c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    UNREACHABLE();
10995e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
10996c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org}
10997e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
10998a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
10999c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.orgvoid HOptimizedGraphBuilder::BuildEmitFixedDoubleArray(
11000c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    Handle<FixedArrayBase> elements,
11001c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    ElementsKind kind,
11002c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    HValue* object_elements) {
110031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HInstruction* boilerplate_elements = Add<HConstant>(elements);
11004c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  int elements_length = elements->length();
11005c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  for (int i = 0; i < elements_length; i++) {
110061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    HValue* key_constant = Add<HConstant>(i);
11007c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    HInstruction* value_instruction =
110081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        Add<HLoadKeyed>(boilerplate_elements, key_constant,
110091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                        static_cast<HValue*>(NULL), kind,
110101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                        ALLOW_RETURN_HOLE);
110111510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant,
110120a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                                           value_instruction, kind);
11013b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org    store->SetFlag(HValue::kAllowUndefinedAsNaN);
11014c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  }
11015c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org}
11016c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
11017c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org
11018c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.orgvoid HOptimizedGraphBuilder::BuildEmitFixedArray(
11019c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    Handle<FixedArrayBase> elements,
11020c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    ElementsKind kind,
11021b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    HValue* object_elements,
1102237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org    AllocationSiteUsageContext* site_context) {
110231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HInstruction* boilerplate_elements = Add<HConstant>(elements);
11024c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  int elements_length = elements->length();
11025c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements);
11026c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  for (int i = 0; i < elements_length; i++) {
11027c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    Handle<Object> value(fast_elements->get(i), isolate());
110281510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    HValue* key_constant = Add<HConstant>(i);
11029c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    if (value->IsJSObject()) {
11030c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      Handle<JSObject> value_object = Handle<JSObject>::cast(value);
11031b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org      Handle<AllocationSite> current_site = site_context->EnterNewScope();
11032b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org      HInstruction* result =
11033b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org          BuildFastLiteral(value_object, site_context);
11034b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org      site_context->ExitScope(current_site, value_object);
110350a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      Add<HStoreKeyed>(object_elements, key_constant, result, kind);
11036c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    } else {
11037c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      HInstruction* value_instruction =
110381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          Add<HLoadKeyed>(boilerplate_elements, key_constant,
110391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                          static_cast<HValue*>(NULL), kind,
110401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                          ALLOW_RETURN_HOLE);
110410a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind);
11042c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    }
11043e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
11044e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
11045e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
11046e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
11047a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) {
11048160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(!HasStackOverflow());
11049160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block() != NULL);
11050160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(current_block()->HasPredecessor());
110515a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  HInstruction* instr = BuildThisFunction();
110525a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  return ast_context()->ReturnInstruction(instr, expr->id());
11053a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11054a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11055a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11056a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitDeclarations(
11057a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    ZoneList<Declaration*>* declarations) {
11058ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  ASSERT(globals_.is_empty());
11059ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  AstVisitor::VisitDeclarations(declarations);
11060ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  if (!globals_.is_empty()) {
1106156454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org    Handle<FixedArray> array =
11062ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com       isolate()->factory()->NewFixedArray(globals_.length(), TENURED);
11063ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i));
1106441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    int flags = DeclareGlobalsEvalFlag::encode(current_info()->is_eval()) |
1106541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org        DeclareGlobalsNativeFlag::encode(current_info()->is_native()) |
11066486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        DeclareGlobalsStrictMode::encode(current_info()->strict_mode());
11067d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    Add<HDeclareGlobals>(array, flags);
11068e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    globals_.Rewind(0);
1106956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  }
110701805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org}
110711805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
110721805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
11073a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitVariableDeclaration(
11074a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    VariableDeclaration* declaration) {
11075ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  VariableProxy* proxy = declaration->proxy();
11076ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  VariableMode mode = declaration->mode();
11077ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  Variable* variable = proxy->var();
11078486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY;
11079ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  switch (variable->location()) {
11080486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    case Variable::UNALLOCATED:
110817028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      globals_.Add(variable->name(), zone());
11082ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      globals_.Add(variable->binding_needs_init()
11083ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com                       ? isolate()->factory()->the_hole_value()
110847028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                       : isolate()->factory()->undefined_value(), zone());
1108556454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org      return;
11086486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    case Variable::PARAMETER:
11087486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    case Variable::LOCAL:
11088ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      if (hole_init) {
11089ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com        HValue* value = graph()->GetConstantHole();
11090ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com        environment()->Bind(variable, value);
11091ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      }
11092ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      break;
11093486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    case Variable::CONTEXT:
11094ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      if (hole_init) {
11095ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com        HValue* value = graph()->GetConstantHole();
11096d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        HValue* context = environment()->context();
110971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        HStoreContextSlot* store = Add<HStoreContextSlot>(
11098ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com            context, variable->index(), HStoreContextSlot::kNoCheck, value);
11099fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        if (store->HasObservableSideEffects()) {
11100c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org          Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE);
11101fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        }
111021805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      }
111031805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org      break;
11104486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org    case Variable::LOOKUP:
11105594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      return Bailout(kUnsupportedLookupSlotInDeclaration);
11106d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  }
11107a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11108a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11109a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11110a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitFunctionDeclaration(
11111a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    FunctionDeclaration* declaration) {
11112ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  VariableProxy* proxy = declaration->proxy();
11113ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  Variable* variable = proxy->var();
11114ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  switch (variable->location()) {
11115ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    case Variable::UNALLOCATED: {
111167028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      globals_.Add(variable->name(), zone());
1111741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      Handle<SharedFunctionInfo> function = Compiler::BuildFunctionInfo(
1111841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org          declaration->fun(), current_info()->script());
11119ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      // Check for stack-overflow exception.
11120ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      if (function.is_null()) return SetStackOverflow();
111217028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      globals_.Add(function, zone());
11122ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      return;
11123ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    }
11124ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    case Variable::PARAMETER:
11125ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    case Variable::LOCAL: {
11126ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      CHECK_ALIVE(VisitForValue(declaration->fun()));
11127ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      HValue* value = Pop();
11128d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      BindIfLive(variable, value);
11129ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      break;
11130ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    }
11131ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    case Variable::CONTEXT: {
11132ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      CHECK_ALIVE(VisitForValue(declaration->fun()));
11133ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      HValue* value = Pop();
11134d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      HValue* context = environment()->context();
111351510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      HStoreContextSlot* store = Add<HStoreContextSlot>(
11136ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com          context, variable->index(), HStoreContextSlot::kNoCheck, value);
11137fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      if (store->HasObservableSideEffects()) {
11138c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org        Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE);
11139fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      }
11140ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com      break;
11141ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    }
11142ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com    case Variable::LOOKUP:
11143594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      return Bailout(kUnsupportedLookupSlotInDeclaration);
11144ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  }
11145812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org}
11146812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
11147812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
11148a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitModuleDeclaration(
11149a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    ModuleDeclaration* declaration) {
11150812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  UNREACHABLE();
11151812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org}
11152812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
11153812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
11154a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitImportDeclaration(
11155a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    ImportDeclaration* declaration) {
11156812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  UNREACHABLE();
11157812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org}
11158812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
11159812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
11160a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitExportDeclaration(
11161a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    ExportDeclaration* declaration) {
11162812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  UNREACHABLE();
1116378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org}
1116478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
1116578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
11166a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitModuleLiteral(ModuleLiteral* module) {
11167ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  UNREACHABLE();
1116878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org}
1116978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
1117078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
11171a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitModuleVariable(ModuleVariable* module) {
11172ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  UNREACHABLE();
1117378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org}
1117478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
1117578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
11176a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitModulePath(ModulePath* module) {
11177ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  UNREACHABLE();
1117878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org}
1117978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
1118078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
11181a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitModuleUrl(ModuleUrl* module) {
11182ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  UNREACHABLE();
1118378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org}
1118478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
1118578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
11186a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::VisitModuleStatement(ModuleStatement* stmt) {
111878e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  UNREACHABLE();
111888e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org}
111898e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
111908e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
11191a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Generators for inline runtime functions.
11192a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Support for types.
11193a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateIsSmi(CallRuntime* call) {
111943a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(call->arguments()->length() == 1);
11195160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11196a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HValue* value = Pop();
11197528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HIsSmiAndBranch* result = New<HIsSmiAndBranch>(value);
111984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnControl(result, call->id());
11199a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11200a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11201a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11202a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateIsSpecObject(CallRuntime* call) {
112033a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(call->arguments()->length() == 1);
11204160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11205a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HValue* value = Pop();
112064f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  HHasInstanceTypeAndBranch* result =
11207dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org      New<HHasInstanceTypeAndBranch>(value,
11208dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org                                     FIRST_SPEC_OBJECT_TYPE,
11209dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org                                     LAST_SPEC_OBJECT_TYPE);
112104f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnControl(result, call->id());
11211a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11212a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11213a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11214a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateIsFunction(CallRuntime* call) {
112153a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(call->arguments()->length() == 1);
11216160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11217a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HValue* value = Pop();
112184f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  HHasInstanceTypeAndBranch* result =
11219dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org      New<HHasInstanceTypeAndBranch>(value, JS_FUNCTION_TYPE);
112204f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnControl(result, call->id());
11221a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11222a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11223a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
112240cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateIsMinusZero(CallRuntime* call) {
112250cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  ASSERT(call->arguments()->length() == 1);
112260cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
112270cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  HValue* value = Pop();
112280cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  HCompareMinusZeroAndBranch* result = New<HCompareMinusZeroAndBranch>(value);
112290cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  return ast_context()->ReturnControl(result, call->id());
112300cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org}
112310cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
112320cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
11233a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateHasCachedArrayIndex(CallRuntime* call) {
112343a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(call->arguments()->length() == 1);
11235160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11236a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HValue* value = Pop();
112374f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  HHasCachedArrayIndexAndBranch* result =
11238db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org      New<HHasCachedArrayIndexAndBranch>(value);
112394f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnControl(result, call->id());
11240a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11241a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11242a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11243a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateIsArray(CallRuntime* call) {
112443a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(call->arguments()->length() == 1);
11245160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11246a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HValue* value = Pop();
112474f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  HHasInstanceTypeAndBranch* result =
11248dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org      New<HHasInstanceTypeAndBranch>(value, JS_ARRAY_TYPE);
112494f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnControl(result, call->id());
11250a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11251a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11252a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11253a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateIsRegExp(CallRuntime* call) {
112543a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(call->arguments()->length() == 1);
11255160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11256a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HValue* value = Pop();
112574f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  HHasInstanceTypeAndBranch* result =
11258dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org      New<HHasInstanceTypeAndBranch>(value, JS_REGEXP_TYPE);
112594f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnControl(result, call->id());
11260a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11261a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11262a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11263a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateIsObject(CallRuntime* call) {
112643a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(call->arguments()->length() == 1);
11265160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
112665f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  HValue* value = Pop();
11267528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HIsObjectAndBranch* result = New<HIsObjectAndBranch>(value);
112684f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnControl(result, call->id());
11269a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11270a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11271a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11272a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateIsNonNegativeSmi(CallRuntime* call) {
11273594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return Bailout(kInlinedRuntimeFunctionIsNonNegativeSmi);
11274a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11275a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11276a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11277a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateIsUndetectableObject(CallRuntime* call) {
112787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  ASSERT(call->arguments()->length() == 1);
112797304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
112807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  HValue* value = Pop();
11281528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HIsUndetectableAndBranch* result = New<HIsUndetectableAndBranch>(value);
112824f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnControl(result, call->id());
11283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11284a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11285a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11286a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf(
112873a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    CallRuntime* call) {
11288594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return Bailout(kInlinedRuntimeFunctionIsStringWrapperSafeForDefaultValueOf);
11289a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11290a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11291a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11292d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com// Support for construct call checks.
11293a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateIsConstructCall(CallRuntime* call) {
112943a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(call->arguments()->length() == 0);
11295c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  if (function_state()->outer() != NULL) {
11296967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    // We are generating graph for inlined function.
11297471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    HValue* value = function_state()->inlining_kind() == CONSTRUCT_CALL_RETURN
11298967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org        ? graph()->GetConstantTrue()
11299967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org        : graph()->GetConstantFalse();
11300967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    return ast_context()->ReturnValue(value);
11301c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  } else {
11302db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org    return ast_context()->ReturnControl(New<HIsConstructCallAndBranch>(),
113034f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                                        call->id());
11304c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  }
11305a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11306a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11307a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11308a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Support for arguments.length and arguments[?].
11309a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateArgumentsLength(CallRuntime* call) {
11310c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org  // Our implementation of arguments (based on this stack frame or an
11311c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org  // adapter below it) does not work for inlined functions.  This runtime
11312c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org  // function is blacklisted by AstNode::IsInlineable.
11313c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org  ASSERT(function_state()->outer() == NULL);
113143a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(call->arguments()->length() == 0);
113151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HInstruction* elements = Add<HArgumentsElements>(false);
11316d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HArgumentsLength* result = New<HArgumentsLength>(elements);
113174f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnInstruction(result, call->id());
11318a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11319a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11320a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11321a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateArguments(CallRuntime* call) {
11322c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org  // Our implementation of arguments (based on this stack frame or an
11323c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org  // adapter below it) does not work for inlined functions.  This runtime
11324c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org  // function is blacklisted by AstNode::IsInlineable.
11325c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org  ASSERT(function_state()->outer() == NULL);
113263a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(call->arguments()->length() == 1);
11327160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11328a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HValue* index = Pop();
113291510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HInstruction* elements = Add<HArgumentsElements>(false);
113301510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HInstruction* length = Add<HArgumentsLength>(elements);
113311510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HInstruction* checked_index = Add<HBoundsCheck>(index, length);
11332db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org  HAccessArgumentsAt* result = New<HAccessArgumentsAt>(
11333db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org      elements, length, checked_index);
113344f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnInstruction(result, call->id());
11335a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11336a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11337a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11338a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Support for accessing the class and value fields of an object.
11339a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) {
11340a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // The special form detected by IsClassOfTest is detected before we get here
11341a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // and does not cause a bailout.
11342594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return Bailout(kInlinedRuntimeFunctionClassOf);
11343a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11344a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11345a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11346a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateValueOf(CallRuntime* call) {
113473a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(call->arguments()->length() == 1);
11348160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
1134909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  HValue* object = Pop();
1135009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
1135109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  IfBuilder if_objectisvalue(this);
1135209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  HValue* objectisvalue = if_objectisvalue.If<HHasInstanceTypeAndBranch>(
1135309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      object, JS_VALUE_TYPE);
1135409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  if_objectisvalue.Then();
1135509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  {
1135609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org    // Return the actual value.
1135709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org    Push(Add<HLoadNamedField>(
1135809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org            object, objectisvalue,
113590a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org            HObjectAccess::ForObservableJSObjectOffset(
113600a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                JSValue::kValueOffset)));
1136109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org    Add<HSimulate>(call->id(), FIXED_SIMULATE);
1136209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  }
1136309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  if_objectisvalue.Else();
1136409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  {
1136509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org    // If the object is not a value return the object.
1136609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org    Push(object);
1136709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org    Add<HSimulate>(call->id(), FIXED_SIMULATE);
1136809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  }
1136909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  if_objectisvalue.End();
1137009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  return ast_context()->ReturnValue(Pop());
11371a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11372a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11373a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11374a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateDateField(CallRuntime* call) {
113754efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  ASSERT(call->arguments()->length() == 2);
113764efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  ASSERT_NE(NULL, call->arguments()->at(1)->AsLiteral());
113771510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Smi* index = Smi::cast(*(call->arguments()->at(1)->AsLiteral()->value()));
113784efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
113794efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  HValue* date = Pop();
11380db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org  HDateField* result = New<HDateField>(date, index);
113814efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org  return ast_context()->ReturnInstruction(result, call->id());
113824efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org}
113834efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
113844efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org
11385a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateOneByteSeqStringSetChar(
1138632280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    CallRuntime* call) {
1138732280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  ASSERT(call->arguments()->length() == 3);
11388f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // We need to follow the evaluation order of full codegen.
1138932280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
1139032280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(2)));
11391f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11392f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  HValue* string = Pop();
1139332280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  HValue* value = Pop();
1139432280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  HValue* index = Pop();
113959af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  Add<HSeqStringSetChar>(String::ONE_BYTE_ENCODING, string,
113969af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org                         index, value);
113979af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  Add<HSimulate>(call->id(), FIXED_SIMULATE);
113989af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  return ast_context()->ReturnValue(graph()->GetConstantUndefined());
1139932280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org}
1140032280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org
1140132280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org
11402a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateTwoByteSeqStringSetChar(
1140332280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org    CallRuntime* call) {
1140432280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  ASSERT(call->arguments()->length() == 3);
11405f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // We need to follow the evaluation order of full codegen.
1140632280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
1140732280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(2)));
11408f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11409f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  HValue* string = Pop();
1141032280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  HValue* value = Pop();
1141132280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  HValue* index = Pop();
114129af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  Add<HSeqStringSetChar>(String::TWO_BYTE_ENCODING, string,
114139af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org                         index, value);
114149af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  Add<HSimulate>(call->id(), FIXED_SIMULATE);
114159af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  return ast_context()->ReturnValue(graph()->GetConstantUndefined());
1141632280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org}
1141732280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org
1141832280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org
11419a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateSetValueOf(CallRuntime* call) {
114202c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  ASSERT(call->arguments()->length() == 2);
114212c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
114222c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
114232c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  HValue* value = Pop();
114242c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  HValue* object = Pop();
114252c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
114262c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // Check if object is a JSValue.
1142709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  IfBuilder if_objectisvalue(this);
1142809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  if_objectisvalue.If<HHasInstanceTypeAndBranch>(object, JS_VALUE_TYPE);
1142909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  if_objectisvalue.Then();
1143009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  {
1143109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org    // Create in-object property store to kValueOffset.
114320a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    Add<HStoreNamedField>(object,
114330a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org        HObjectAccess::ForObservableJSObjectOffset(JSValue::kValueOffset),
114340a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org        value);
11435f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (!ast_context()->IsEffect()) {
11436f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      Push(value);
11437f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    }
1143809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org    Add<HSimulate>(call->id(), FIXED_SIMULATE);
1143909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  }
1144009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  if_objectisvalue.Else();
1144109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  {
1144209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org    // Nothing to do in this case.
11443f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (!ast_context()->IsEffect()) {
11444f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      Push(value);
11445f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    }
1144609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org    Add<HSimulate>(call->id(), FIXED_SIMULATE);
1144709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  }
1144809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  if_objectisvalue.End();
11449f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (!ast_context()->IsEffect()) {
11450f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    Drop(1);
11451f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
114522c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  return ast_context()->ReturnValue(value);
11453a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11454a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11455a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11456a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Fast support for charCodeAt(n).
11457a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) {
114583a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(call->arguments()->length() == 2);
11459160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11460160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
114610a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  HValue* index = Pop();
114620a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  HValue* string = Pop();
11463d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* result = BuildStringCharCodeAt(string, index);
114644f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnInstruction(result, call->id());
11465a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11466a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11467a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11468a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Fast support for string.charAt(n) and string[n].
11469a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) {
11470b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  ASSERT(call->arguments()->length() == 1);
11471160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11472b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  HValue* char_code = Pop();
11473db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org  HInstruction* result = NewUncasted<HStringCharFromCode>(char_code);
114744f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnInstruction(result, call->id());
11475a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11476a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11477a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11478a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Fast support for string.charAt(n) and string[n].
11479a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateStringCharAt(CallRuntime* call) {
11480b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  ASSERT(call->arguments()->length() == 2);
11481160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11482160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
11483b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  HValue* index = Pop();
11484b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  HValue* string = Pop();
11485d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* char_code = BuildStringCharCodeAt(string, index);
11486b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  AddInstruction(char_code);
11487db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org  HInstruction* result = NewUncasted<HStringCharFromCode>(char_code);
114884f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnInstruction(result, call->id());
11489a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11490a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11491a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11492a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Fast support for object equality testing.
11493a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateObjectEquals(CallRuntime* call) {
114943a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(call->arguments()->length() == 2);
11495160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11496160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
11497a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HValue* right = Pop();
11498a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HValue* left = Pop();
114994f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  HCompareObjectEqAndBranch* result =
11500d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      New<HCompareObjectEqAndBranch>(left, right);
115014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnControl(result, call->id());
11502a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11503a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11504a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11505a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Fast support for StringAdd.
11506a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) {
115073a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT_EQ(2, call->arguments()->length());
11508ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11509ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
11510ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  HValue* right = Pop();
11511ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  HValue* left = Pop();
115120f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HInstruction* result = NewUncasted<HStringAdd>(left, right);
115134f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnInstruction(result, call->id());
11514a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11515a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11516a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11517a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Fast support for SubString.
11518a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) {
115193a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT_EQ(3, call->arguments()->length());
11520bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  CHECK_ALIVE(VisitExpressions(call->arguments()));
11521bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  PushArgumentsFromEnvironment(call->arguments()->length());
115228e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  HCallStub* result = New<HCallStub>(CodeStub::SubString, 3);
115234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnInstruction(result, call->id());
11524a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11525a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11526a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11527a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Fast support for StringCompare.
11528a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateStringCompare(CallRuntime* call) {
115293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT_EQ(2, call->arguments()->length());
11530bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  CHECK_ALIVE(VisitExpressions(call->arguments()));
11531bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  PushArgumentsFromEnvironment(call->arguments()->length());
115328e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  HCallStub* result = New<HCallStub>(CodeStub::StringCompare, 2);
115334f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnInstruction(result, call->id());
11534a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11535a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11536a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11537a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Support for direct calls from JavaScript to native RegExp code.
11538a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) {
115393a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT_EQ(4, call->arguments()->length());
11540bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  CHECK_ALIVE(VisitExpressions(call->arguments()));
11541bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  PushArgumentsFromEnvironment(call->arguments()->length());
115428e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  HCallStub* result = New<HCallStub>(CodeStub::RegExpExec, 4);
115434f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnInstruction(result, call->id());
11544a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11545a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11546a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11547ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateDoubleLo(CallRuntime* call) {
11548ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  ASSERT_EQ(1, call->arguments()->length());
11549ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11550ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  HValue* value = Pop();
11551ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  HInstruction* result = NewUncasted<HDoubleBits>(value, HDoubleBits::LOW);
11552ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  return ast_context()->ReturnInstruction(result, call->id());
11553ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org}
11554ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
11555ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
11556ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateDoubleHi(CallRuntime* call) {
11557ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  ASSERT_EQ(1, call->arguments()->length());
11558ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11559ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  HValue* value = Pop();
11560ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  HInstruction* result = NewUncasted<HDoubleBits>(value, HDoubleBits::HIGH);
11561ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  return ast_context()->ReturnInstruction(result, call->id());
11562ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org}
11563ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
11564ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
11565ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateConstructDouble(CallRuntime* call) {
11566ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  ASSERT_EQ(2, call->arguments()->length());
11567ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11568ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
11569ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  HValue* lo = Pop();
11570ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  HValue* hi = Pop();
11571ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  HInstruction* result = NewUncasted<HConstructDouble>(hi, lo);
11572ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  return ast_context()->ReturnInstruction(result, call->id());
11573ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org}
11574ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
11575ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
11576a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Construct a RegExp exec result with two in-object properties.
11577a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) {
115783a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT_EQ(3, call->arguments()->length());
1157909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
1158009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
1158109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(2)));
1158209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  HValue* input = Pop();
1158309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  HValue* index = Pop();
1158409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  HValue* length = Pop();
1158509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  HValue* result = BuildRegExpConstructResult(length, index, input);
1158609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  return ast_context()->ReturnValue(result);
11587a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11588a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11589a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11590a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Support for fast native caches.
11591a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) {
11592594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return Bailout(kInlinedRuntimeFunctionGetFromCache);
11593a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11594a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11595a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11596a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Fast support for number to string.
11597a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) {
115983a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT_EQ(1, call->arguments()->length());
115993d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
116003d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  HValue* number = Pop();
116016d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  HValue* result = BuildNumberToString(number, Type::Any(zone()));
116023d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  return ast_context()->ReturnValue(result);
11603a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11604a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11605a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11606a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Fast call for custom callbacks.
11607a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) {
11608160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  // 1 ~ The function to call is not itself an argument to the call.
11609160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  int arg_count = call->arguments()->length() - 1;
11610160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  ASSERT(arg_count >= 1);  // There's always at least a receiver.
11611160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org
11612bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  CHECK_ALIVE(VisitExpressions(call->arguments()));
11613bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  // The function is the last argument
11614160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  HValue* function = Pop();
11615bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  // Push the arguments to the stack
11616bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  PushArgumentsFromEnvironment(arg_count);
11617c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
1161825530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org  IfBuilder if_is_jsfunction(this);
1161925530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org  if_is_jsfunction.If<HHasInstanceTypeAndBranch>(function, JS_FUNCTION_TYPE);
11620c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
1162125530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org  if_is_jsfunction.Then();
1162225530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org  {
1162325530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org    HInstruction* invoke_result =
1162425530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org        Add<HInvokeFunction>(function, arg_count);
1162525530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org    if (!ast_context()->IsEffect()) {
1162625530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org      Push(invoke_result);
1162725530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org    }
1162825530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org    Add<HSimulate>(call->id(), FIXED_SIMULATE);
1162925530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org  }
1163025530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org
1163125530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org  if_is_jsfunction.Else();
1163225530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org  {
1163325530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org    HInstruction* call_result =
1163425530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org        Add<HCallFunction>(function, arg_count);
1163525530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org    if (!ast_context()->IsEffect()) {
1163625530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org      Push(call_result);
1163725530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org    }
1163825530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org    Add<HSimulate>(call->id(), FIXED_SIMULATE);
1163925530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org  }
1164025530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org  if_is_jsfunction.End();
1164125530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org
1164225530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org  if (ast_context()->IsEffect()) {
1164325530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org    // EffectContext::ReturnValue ignores the value, so we can just pass
1164425530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org    // 'undefined' (as we do not have the call result anymore).
1164525530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org    return ast_context()->ReturnValue(graph()->GetConstantUndefined());
1164625530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org  } else {
1164725530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org    return ast_context()->ReturnValue(Pop());
1164825530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org  }
11649a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11650a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11651a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11652a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Fast call to math functions.
11653a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateMathPow(CallRuntime* call) {
116543a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT_EQ(2, call->arguments()->length());
11655160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11656160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
116575f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  HValue* right = Pop();
116585f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  HValue* left = Pop();
11659db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org  HInstruction* result = NewUncasted<HPower>(left, right);
116604f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnInstruction(result, call->id());
11661a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11662a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11663a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11664285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateMathLogRT(CallRuntime* call) {
116654f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  ASSERT(call->arguments()->length() == 1);
116664f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
116674f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  HValue* value = Pop();
116684f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org  HInstruction* result = NewUncasted<HUnaryMathOperation>(value, kMathLog);
116694f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnInstruction(result, call->id());
11670a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11671a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11672a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11673aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateMathSqrtRT(CallRuntime* call) {
11674e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ASSERT(call->arguments()->length() == 1);
11675e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11676e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  HValue* value = Pop();
11677f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  HInstruction* result = NewUncasted<HUnaryMathOperation>(value, kMathSqrt);
11678e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  return ast_context()->ReturnInstruction(result, call->id());
11679a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11680a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11681a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11682a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateGetCachedArrayIndex(CallRuntime* call) {
116833a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT(call->arguments()->length() == 1);
11684160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
1168549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  HValue* value = Pop();
11686db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org  HGetCachedArrayIndex* result = New<HGetCachedArrayIndex>(value);
116874f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  return ast_context()->ReturnInstruction(result, call->id());
11688a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11689a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11690a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11691a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HOptimizedGraphBuilder::GenerateFastAsciiArrayJoin(CallRuntime* call) {
11692594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return Bailout(kInlinedRuntimeFunctionFastAsciiArrayJoin);
11693a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11694a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11695a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11696ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org// Support for generators.
116978a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.orgvoid HOptimizedGraphBuilder::GenerateGeneratorNext(CallRuntime* call) {
11698594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return Bailout(kInlinedRuntimeFunctionGeneratorNext);
11699ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
11700ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
11701ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
11702ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgvoid HOptimizedGraphBuilder::GenerateGeneratorThrow(CallRuntime* call) {
11703594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  return Bailout(kInlinedRuntimeFunctionGeneratorThrow);
11704ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
11705ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
11706ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
1170793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.orgvoid HOptimizedGraphBuilder::GenerateDebugBreakInOptimizedCode(
1170893a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org    CallRuntime* call) {
11709db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org  Add<HDebugBreak>();
1171093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  return ast_context()->ReturnValue(graph()->GetConstant0());
1171193a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org}
1171293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
1171393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
11714f05311f128ad22c89cfb6063d9375945c02239b5machenbach@chromium.orgvoid HOptimizedGraphBuilder::GenerateDebugCallbackSupportsStepping(
11715f05311f128ad22c89cfb6063d9375945c02239b5machenbach@chromium.org    CallRuntime* call) {
11716f05311f128ad22c89cfb6063d9375945c02239b5machenbach@chromium.org  ASSERT(call->arguments()->length() == 1);
11717f05311f128ad22c89cfb6063d9375945c02239b5machenbach@chromium.org  // Debugging is not supported in optimized code.
11718f05311f128ad22c89cfb6063d9375945c02239b5machenbach@chromium.org  return ast_context()->ReturnValue(graph()->GetConstantFalse());
11719f05311f128ad22c89cfb6063d9375945c02239b5machenbach@chromium.org}
11720f05311f128ad22c89cfb6063d9375945c02239b5machenbach@chromium.org
11721f05311f128ad22c89cfb6063d9375945c02239b5machenbach@chromium.org
11722a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#undef CHECK_BAILOUT
11723160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org#undef CHECK_ALIVE
11724a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11725a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11726a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgHEnvironment::HEnvironment(HEnvironment* outer,
11727a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                           Scope* scope,
117287028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                           Handle<JSFunction> closure,
117297028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                           Zone* zone)
11730a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    : closure_(closure),
117317028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      values_(0, zone),
11732967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      frame_type_(JS_FUNCTION),
11733a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      parameter_count_(0),
1173483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      specials_count_(1),
11735a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      local_count_(0),
11736a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      outer_(outer),
1173756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      entry_(NULL),
11738a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      pop_count_(0),
11739a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      push_count_(0),
11740471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      ast_id_(BailoutId::None()),
117417028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      zone_(zone) {
117421e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  Scope* declaration_scope = scope->DeclarationScope();
117431e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  Initialize(declaration_scope->num_parameters() + 1,
117441e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org             declaration_scope->num_stack_slots(), 0);
11745a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11746a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11747a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1174809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.orgHEnvironment::HEnvironment(Zone* zone, int parameter_count)
11749a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    : values_(0, zone),
11750a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      frame_type_(STUB),
1175109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org      parameter_count_(parameter_count),
1175209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org      specials_count_(1),
11753a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      local_count_(0),
11754a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      outer_(NULL),
11755a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      entry_(NULL),
11756a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      pop_count_(0),
11757a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      push_count_(0),
11758a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      ast_id_(BailoutId::None()),
11759a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      zone_(zone) {
1176009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Initialize(parameter_count, 0, 0);
11761a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
11762a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
11763a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
117647028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.orgHEnvironment::HEnvironment(const HEnvironment* other, Zone* zone)
117657028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    : values_(0, zone),
11766967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      frame_type_(JS_FUNCTION),
11767a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      parameter_count_(0),
1176894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      specials_count_(0),
11769a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      local_count_(0),
11770a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      outer_(NULL),
1177156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      entry_(NULL),
11772a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      pop_count_(0),
11773a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      push_count_(0),
117747028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      ast_id_(other->ast_id()),
117757028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      zone_(zone) {
11776a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Initialize(other);
11777a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11778a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11779a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11780659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgHEnvironment::HEnvironment(HEnvironment* outer,
11781659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org                           Handle<JSFunction> closure,
11782967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org                           FrameType frame_type,
117837028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                           int arguments,
117847028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                           Zone* zone)
11785659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    : closure_(closure),
117867028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      values_(arguments, zone),
11787967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org      frame_type_(frame_type),
11788659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      parameter_count_(arguments),
11789b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      specials_count_(0),
11790659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      local_count_(0),
11791659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      outer_(outer),
1179256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org      entry_(NULL),
11793659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      pop_count_(0),
11794659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      push_count_(0),
11795471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org      ast_id_(BailoutId::None()),
117967028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      zone_(zone) {
11797659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org}
11798659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
11799659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
11800a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HEnvironment::Initialize(int parameter_count,
11801a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                              int local_count,
11802a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                              int stack_height) {
11803a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  parameter_count_ = parameter_count;
11804a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  local_count_ = local_count;
11805a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11806a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Avoid reallocating the temporaries' backing store on the first Push.
1180783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  int total = parameter_count + specials_count_ + local_count + stack_height;
118087028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  values_.Initialize(total + 4, zone());
118097028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  for (int i = 0; i < total; ++i) values_.Add(NULL, zone());
11810a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11811a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11812a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
118135d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid HEnvironment::Initialize(const HEnvironment* other) {
118145d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  closure_ = other->closure();
118157028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  values_.AddAll(other->values_, zone());
1181659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  assigned_variables_.Union(other->assigned_variables_, zone());
11817967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  frame_type_ = other->frame_type_;
118185d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  parameter_count_ = other->parameter_count_;
118195d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  local_count_ = other->local_count_;
118205d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  if (other->outer_ != NULL) outer_ = other->outer_->Copy();  // Deep copy.
1182156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  entry_ = other->entry_;
118225d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  pop_count_ = other->pop_count_;
118235d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  push_count_ = other->push_count_;
1182494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  specials_count_ = other->specials_count_;
118255d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  ast_id_ = other->ast_id_;
118265d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org}
118275d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org
118285d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org
11829a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) {
11830a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(!block->IsLoopHeader());
11831a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ASSERT(values_.length() == other->values_.length());
11832a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11833a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int length = values_.length();
11834a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < length; ++i) {
11835a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    HValue* value = values_[i];
11836a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (value != NULL && value->IsPhi() && value->block() == block) {
11837a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // There is already a phi for the i'th value.
11838a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      HPhi* phi = HPhi::cast(value);
11839a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // Assert index is correct and that we haven't missed an incoming edge.
11840ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org      ASSERT(phi->merged_index() == i || !phi->HasMergedIndex());
11841a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      ASSERT(phi->OperandCount() == block->predecessors()->length());
11842a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      phi->AddInput(other->values_[i]);
11843a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    } else if (values_[i] != other->values_[i]) {
11844a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // There is a fresh value on the incoming edge, a phi is needed.
11845a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      ASSERT(values_[i] != NULL && other->values_[i] != NULL);
11846ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org      HPhi* phi = block->AddNewPhi(i);
11847a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      HValue* old_value = values_[i];
11848a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      for (int j = 0; j < block->predecessors()->length(); j++) {
11849a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        phi->AddInput(old_value);
11850a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
11851a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      phi->AddInput(other->values_[i]);
11852a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      this->values_[i] = phi;
11853a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
11854a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
11855a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11856a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11857a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
118585d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid HEnvironment::Bind(int index, HValue* value) {
118595d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  ASSERT(value != NULL);
1186059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  assigned_variables_.Add(index, zone());
118615d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  values_[index] = value;
11862a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11863a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11864a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
118655d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgbool HEnvironment::HasExpressionAt(int index) const {
1186683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  return index >= parameter_count_ + specials_count_ + local_count_;
118675d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org}
118685d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org
118695d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org
118705d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgbool HEnvironment::ExpressionStackIsEmpty() const {
11871be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  ASSERT(length() >= first_expression_index());
11872be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  return length() == first_expression_index();
118735d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org}
118745d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org
118755d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org
118765d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid HEnvironment::SetExpressionStackAt(int index_from_top, HValue* value) {
118775d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  int count = index_from_top + 1;
118785d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  int index = values_.length() - count;
118795d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  ASSERT(HasExpressionAt(index));
118805d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  // The push count must include at least the element in question or else
118815d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  // the new value will not be included in this environment's history.
118825d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  if (push_count_ < count) {
118835d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org    // This is the same effect as popping then re-pushing 'count' elements.
118845d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org    pop_count_ += (count - push_count_);
118855d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org    push_count_ = count;
118865d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  }
118875d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  values_[index] = value;
118885d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org}
118895d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org
118905d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org
118915d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid HEnvironment::Drop(int count) {
118925d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  for (int i = 0; i < count; ++i) {
118935d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org    Pop();
11894a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
11895a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11896a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11897a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11898a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgHEnvironment* HEnvironment::Copy() const {
118997028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  return new(zone()) HEnvironment(this, zone());
11900a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11901a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11902a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11903a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgHEnvironment* HEnvironment::CopyWithoutHistory() const {
11904a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HEnvironment* result = Copy();
11905a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  result->ClearHistory();
11906a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return result;
11907a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11908a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11909a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11910a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgHEnvironment* HEnvironment::CopyAsLoopHeader(HBasicBlock* loop_header) const {
11911a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HEnvironment* new_env = Copy();
11912a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < values_.length(); ++i) {
11913ad75d6febf45d81dda1f4cd158c7eb97c0408a25danno@chromium.org    HPhi* phi = loop_header->AddNewPhi(i);
11914a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    phi->AddInput(values_[i]);
11915a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    new_env->values_[i] = phi;
11916a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
11917a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  new_env->ClearHistory();
11918a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return new_env;
11919a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11920a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11921a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11922967e270a034432457500dbf950d2c4951a929e52ulan@chromium.orgHEnvironment* HEnvironment::CreateStubEnvironment(HEnvironment* outer,
11923967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org                                                  Handle<JSFunction> target,
11924967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org                                                  FrameType frame_type,
11925967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org                                                  int arguments) const {
119267028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  HEnvironment* new_env =
119277028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      new(zone()) HEnvironment(outer, target, frame_type,
119287028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                               arguments + 1, zone());
11929967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  for (int i = 0; i <= arguments; ++i) {  // Include receiver.
11930967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    new_env->Push(ExpressionStackAt(arguments - i));
11931967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  }
11932967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  new_env->ClearHistory();
11933967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  return new_env;
11934967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org}
11935967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org
11936967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org
1193740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.orgHEnvironment* HEnvironment::CopyForInlining(
1193840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    Handle<JSFunction> target,
11939659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    int arguments,
1194040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    FunctionLiteral* function,
1194140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    HConstant* undefined,
11942e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org    InliningKind inlining_kind) const {
11943967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  ASSERT(frame_type() == JS_FUNCTION);
11944659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
11945a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Outer environment is a copy of this one without the arguments.
11946a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int arity = function->scope()->num_parameters();
11947659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
11948a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HEnvironment* outer = Copy();
11949659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  outer->Drop(arguments + 1);  // Including receiver.
11950a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  outer->ClearHistory();
11951659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
11952471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  if (inlining_kind == CONSTRUCT_CALL_RETURN) {
11953967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    // Create artificial constructor stub environment.  The receiver should
11954967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    // actually be the constructor function, but we pass the newly allocated
11955967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    // object instead, DoComputeConstructStubFrame() relies on that.
11956967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    outer = CreateStubEnvironment(outer, target, JS_CONSTRUCT, arguments);
11957de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  } else if (inlining_kind == GETTER_CALL_RETURN) {
11958de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org    // We need an additional StackFrame::INTERNAL frame for restoring the
11959de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org    // correct context.
11960de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org    outer = CreateStubEnvironment(outer, target, JS_GETTER, arguments);
11961471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  } else if (inlining_kind == SETTER_CALL_RETURN) {
11962471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    // We need an additional StackFrame::INTERNAL frame for temporarily saving
11963471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    // the argument of the setter, see StoreStubCompiler::CompileStoreViaSetter.
11964471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    outer = CreateStubEnvironment(outer, target, JS_SETTER, arguments);
11965967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org  }
11966967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org
11967659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  if (arity != arguments) {
11968659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    // Create artificial arguments adaptation environment.
11969967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org    outer = CreateStubEnvironment(outer, target, ARGUMENTS_ADAPTOR, arguments);
11970659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  }
11971659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
1197274f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  HEnvironment* inner =
119735a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org      new(zone()) HEnvironment(outer, function->scope(), target, zone());
11974a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Get the argument values from the original environment.
119753cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  for (int i = 0; i <= arity; ++i) {  // Include receiver.
11976659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    HValue* push = (i <= arguments) ?
11977659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org        ExpressionStackAt(arguments - i) : undefined;
119783cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org    inner->SetValueAt(i, push);
11979a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
11980d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  inner->SetValueAt(arity + 1, context());
1198183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  for (int i = arity + 2; i < inner->length(); ++i) {
1198283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    inner->SetValueAt(i, undefined);
11983a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
11984a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11985471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  inner->set_ast_id(BailoutId::FunctionEntry());
11986a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  return inner;
11987a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
11988a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11989a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11990a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HEnvironment::PrintTo(StringStream* stream) {
119915d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  for (int i = 0; i < length(); i++) {
11992a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (i == 0) stream->Add("parameters\n");
1199383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    if (i == parameter_count()) stream->Add("specials\n");
1199483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    if (i == parameter_count() + specials_count()) stream->Add("locals\n");
1199583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    if (i == parameter_count() + specials_count() + local_count()) {
11996659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      stream->Add("expressions\n");
1199783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    }
11998a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    HValue* val = values_.at(i);
11999a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    stream->Add("%d: ", i);
12000a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (val != NULL) {
12001a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      val->PrintNameTo(stream);
12002a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    } else {
12003a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      stream->Add("NULL");
12004a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
12005a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    stream->Add("\n");
12006a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
12007659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  PrintF("\n");
12008a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
12009a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12010a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12011a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HEnvironment::PrintToStd() {
12012a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HeapStringAllocator string_allocator;
12013a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  StringStream trace(&string_allocator);
12014a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  PrintTo(&trace);
12015afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org  PrintF("%s", trace.ToCString().get());
12016a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
12017a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12018a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12019a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid HTracer::TraceCompilation(CompilationInfo* info) {
12020a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Tag tag(this, "compilation");
12021a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (info->IsOptimizing()) {
12022a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    Handle<String> name = info->function()->debug_name();
12023afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    PrintStringProperty("name", name->ToCString().get());
12024f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    PrintIndent();
12025f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    trace_.Add("method \"%s:%d\"\n",
12026f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org               name->ToCString().get(),
12027f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org               info->optimization_id());
12028a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  } else {
12029a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    CodeStub::Major major_key = info->code_stub()->MajorKey();
12030a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    PrintStringProperty("name", CodeStub::MajorName(major_key, false));
12031a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    PrintStringProperty("method", "stub");
12032a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
12033a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  PrintLongProperty("date", static_cast<int64_t>(OS::TimeCurrentMillis()));
12034a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
12035a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12036a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1203728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgvoid HTracer::TraceLithium(const char* name, LChunk* chunk) {
120389af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  ASSERT(!chunk->isolate()->concurrent_recompilation_enabled());
120391fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  AllowHandleDereference allow_deref;
120401fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  AllowDeferredHandleDereference allow_deferred_deref;
12041a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Trace(name, chunk->graph(), chunk);
12042a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
12043a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12044a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12045a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HTracer::TraceHydrogen(const char* name, HGraph* graph) {
120469af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  ASSERT(!graph->isolate()->concurrent_recompilation_enabled());
120471fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  AllowHandleDereference allow_deref;
120481fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  AllowDeferredHandleDereference allow_deferred_deref;
12049a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Trace(name, graph, NULL);
12050a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
12051a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12052a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1205328583c92ca8f528df625800519088ac88996d504jkummerow@chromium.orgvoid HTracer::Trace(const char* name, HGraph* graph, LChunk* chunk) {
12054a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Tag tag(this, "cfg");
12055a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  PrintStringProperty("name", name);
12056a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  const ZoneList<HBasicBlock*>* blocks = graph->blocks();
12057a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < blocks->length(); i++) {
12058a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    HBasicBlock* current = blocks->at(i);
12059a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Tag block_tag(this, "block");
12060a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    PrintBlockProperty("name", current->block_id());
12061a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    PrintIntProperty("from_bci", -1);
12062a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    PrintIntProperty("to_bci", -1);
12063a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12064a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (!current->predecessors()->is_empty()) {
12065a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      PrintIndent();
12066a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      trace_.Add("predecessors");
12067a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      for (int j = 0; j < current->predecessors()->length(); ++j) {
12068a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        trace_.Add(" \"B%d\"", current->predecessors()->at(j)->block_id());
12069a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
12070a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      trace_.Add("\n");
12071a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    } else {
12072a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      PrintEmptyProperty("predecessors");
12073a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
12074a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
120756d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    if (current->end()->SuccessorCount() == 0) {
12076a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      PrintEmptyProperty("successors");
120776d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    } else  {
120786d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      PrintIndent();
120796d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      trace_.Add("successors");
120806d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      for (HSuccessorIterator it(current->end()); !it.Done(); it.Advance()) {
120816d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org        trace_.Add(" \"B%d\"", it.Current()->block_id());
120826d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      }
120836d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      trace_.Add("\n");
12084a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
12085a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12086a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    PrintEmptyProperty("xhandlers");
120874ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org
120884ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org    {
120894ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org      PrintIndent();
120904ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org      trace_.Add("flags");
120914ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org      if (current->IsLoopSuccessorDominator()) {
120924ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org        trace_.Add(" \"dom-loop-succ\"");
120934ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org      }
120944ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org      if (current->IsUnreachable()) {
120954ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org        trace_.Add(" \"dead\"");
120964ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org      }
120974ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org      if (current->is_osr_entry()) {
120984ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org        trace_.Add(" \"osr\"");
120994ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org      }
121004ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org      trace_.Add("\n");
121014ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org    }
12102a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12103a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (current->dominator() != NULL) {
12104a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      PrintBlockProperty("dominator", current->dominator()->block_id());
12105a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
12106a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1210783e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org    PrintIntProperty("loop_depth", current->LoopNestingDepth());
1210883e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org
12109a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (chunk != NULL) {
12110a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      int first_index = current->first_instruction_index();
12111a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      int last_index = current->last_instruction_index();
12112a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      PrintIntProperty(
12113a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          "first_lir_id",
12114a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          LifetimePosition::FromInstructionIndex(first_index).Value());
12115a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      PrintIntProperty(
12116a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          "last_lir_id",
12117a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          LifetimePosition::FromInstructionIndex(last_index).Value());
12118a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
12119a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12120a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    {
12121a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      Tag states_tag(this, "states");
12122a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      Tag locals_tag(this, "locals");
12123a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      int total = current->phis()->length();
1212483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      PrintIntProperty("size", current->phis()->length());
1212583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      PrintStringProperty("method", "None");
12126a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      for (int j = 0; j < total; ++j) {
12127a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        HPhi* phi = current->phis()->at(j);
1212883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org        PrintIndent();
12129a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        trace_.Add("%d ", phi->merged_index());
12130a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        phi->PrintNameTo(&trace_);
12131a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        trace_.Add(" ");
12132a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        phi->PrintTo(&trace_);
12133a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        trace_.Add("\n");
12134a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
12135a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
12136a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12137a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    {
12138a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      Tag HIR_tag(this, "HIR");
1213993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org      for (HInstructionIterator it(current); !it.Done(); it.Advance()) {
1214093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org        HInstruction* instruction = it.Current();
121413847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com        int uses = instruction->UseCount();
1214283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org        PrintIndent();
12143f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        trace_.Add("0 %d ", uses);
12144a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        instruction->PrintNameTo(&trace_);
12145a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        trace_.Add(" ");
12146a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        instruction->PrintTo(&trace_);
12147f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        if (FLAG_hydrogen_track_positions &&
12148f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org            instruction->has_position() &&
12149f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org            instruction->position().raw() != 0) {
12150f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          const HSourcePosition pos = instruction->position();
12151f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          trace_.Add(" pos:");
12152f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          if (pos.inlining_id() != 0) {
12153f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org            trace_.Add("%d_", pos.inlining_id());
12154f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          }
12155f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org          trace_.Add("%d", pos.position());
12156f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        }
12157a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        trace_.Add(" <|@\n");
12158a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
12159a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
12160a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12161a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12162a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (chunk != NULL) {
12163a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      Tag LIR_tag(this, "LIR");
12164a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      int first_index = current->first_instruction_index();
12165a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      int last_index = current->last_instruction_index();
12166a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      if (first_index != -1 && last_index != -1) {
12167a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        const ZoneList<LInstruction*>* instructions = chunk->instructions();
12168a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        for (int i = first_index; i <= last_index; ++i) {
12169a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          LInstruction* linstr = instructions->at(i);
12170a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          if (linstr != NULL) {
1217183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org            PrintIndent();
12172a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            trace_.Add("%d ",
12173a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                       LifetimePosition::FromInstructionIndex(i).Value());
12174a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            linstr->PrintTo(&trace_);
12175af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org            trace_.Add(" [hir:");
12176af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org            linstr->hydrogen_value()->PrintNameTo(&trace_);
12177af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org            trace_.Add("]");
12178a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            trace_.Add(" <|@\n");
12179a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          }
12180a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        }
12181a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
12182a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
12183a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
12184a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
12185a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12186a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12187a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HTracer::TraceLiveRanges(const char* name, LAllocator* allocator) {
12188a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Tag tag(this, "intervals");
12189a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  PrintStringProperty("name", name);
12190a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12191b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  const Vector<LiveRange*>* fixed_d = allocator->fixed_double_live_ranges();
12192a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < fixed_d->length(); ++i) {
121937028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    TraceLiveRange(fixed_d->at(i), "fixed", allocator->zone());
12194a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
12195a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12196b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  const Vector<LiveRange*>* fixed = allocator->fixed_live_ranges();
12197a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < fixed->length(); ++i) {
121987028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    TraceLiveRange(fixed->at(i), "fixed", allocator->zone());
12199a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
12200a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12201a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  const ZoneList<LiveRange*>* live_ranges = allocator->live_ranges();
12202a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < live_ranges->length(); ++i) {
122037028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    TraceLiveRange(live_ranges->at(i), "object", allocator->zone());
12204a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
12205a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
12206a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12207a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
122087028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.orgvoid HTracer::TraceLiveRange(LiveRange* range, const char* type,
122097028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                             Zone* zone) {
12210a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  if (range != NULL && !range->IsEmpty()) {
1221183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    PrintIndent();
12212a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    trace_.Add("%d %s", range->id(), type);
12213a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (range->HasRegisterAssigned()) {
122147028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      LOperand* op = range->CreateAssignedOperand(zone);
12215a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      int assigned_reg = op->index();
12216a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      if (op->IsDoubleRegister()) {
12217a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        trace_.Add(" \"%s\"",
12218a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                   DoubleRegister::AllocationIndexToString(assigned_reg));
12219a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      } else {
12220a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        ASSERT(op->IsRegister());
12221a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        trace_.Add(" \"%s\"", Register::AllocationIndexToString(assigned_reg));
12222a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
12223a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    } else if (range->IsSpilled()) {
12224a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      LOperand* op = range->TopLevel()->GetSpillOperand();
12225a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      if (op->IsDoubleStackSlot()) {
12226a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        trace_.Add(" \"double_stack:%d\"", op->index());
12227a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      } else {
12228a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        ASSERT(op->IsStackSlot());
12229a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        trace_.Add(" \"stack:%d\"", op->index());
12230a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
12231a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
12232a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    int parent_index = -1;
12233a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (range->IsChild()) {
12234a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      parent_index = range->parent()->id();
12235a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    } else {
12236a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      parent_index = range->id();
12237a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
12238a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    LOperand* op = range->FirstHint();
12239a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    int hint_index = -1;
12240fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    if (op != NULL && op->IsUnallocated()) {
12241fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org      hint_index = LUnallocated::cast(op)->virtual_register();
12242fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    }
12243a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    trace_.Add(" %d %d", parent_index, hint_index);
12244a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    UseInterval* cur_interval = range->first_interval();
122453a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    while (cur_interval != NULL && range->Covers(cur_interval->start())) {
12246a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      trace_.Add(" [%d, %d[",
12247a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                 cur_interval->start().Value(),
12248a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                 cur_interval->end().Value());
12249a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      cur_interval = cur_interval->next();
12250a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
12251a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12252a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    UsePosition* current_pos = range->first_pos();
12253a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    while (current_pos != NULL) {
122543a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      if (current_pos->RegisterIsBeneficial() || FLAG_trace_all_uses) {
12255a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        trace_.Add(" %d M", current_pos->pos().Value());
12256a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
12257a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      current_pos = current_pos->next();
12258a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
12259a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12260a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    trace_.Add(" \"\"\n");
12261a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
12262a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
12263a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12264a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12265a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HTracer::FlushToFile() {
12266afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org  AppendChars(filename_.start(), trace_.ToCString().get(), trace_.length(),
12267afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org              false);
12268a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  trace_.Reset();
12269a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
12270a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12271a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12272b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.orgvoid HStatistics::Initialize(CompilationInfo* info) {
12273003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  if (info->shared_info().is_null()) return;
12274b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  source_size_ += info->shared_info()->SourceSize();
12275b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org}
12276b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org
12277b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org
12278a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid HStatistics::Print() {
12279a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  PrintF("Timing results:\n");
12280dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  TimeDelta sum;
12281dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  for (int i = 0; i < times_.length(); ++i) {
12282dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    sum += times_[i];
12283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
12284a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12285a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < names_.length(); ++i) {
122861510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    PrintF("%32s", names_[i]);
12287dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    double ms = times_[i].InMillisecondsF();
12288dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    double percent = times_[i].PercentOf(sum);
122891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    PrintF(" %8.3f ms / %4.1f %% ", ms, percent);
12290c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
12291c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    unsigned size = sizes_[i];
12292c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    double size_percent = static_cast<double>(size) * 100 / total_size_;
12293068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org    PrintF(" %9u bytes / %4.1f %%\n", size, size_percent);
12294a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
122958e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
12296068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  PrintF("----------------------------------------"
12297068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org         "---------------------------------------\n");
12298dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  TimeDelta total = create_graph_ + optimize_graph_ + generate_code_;
122991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  PrintF("%32s %8.3f ms / %4.1f %% \n",
123008e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org         "Create graph",
12301dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org         create_graph_.InMillisecondsF(),
12302dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org         create_graph_.PercentOf(total));
123031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  PrintF("%32s %8.3f ms / %4.1f %% \n",
123048e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org         "Optimize graph",
12305dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org         optimize_graph_.InMillisecondsF(),
12306dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org         optimize_graph_.PercentOf(total));
123071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  PrintF("%32s %8.3f ms / %4.1f %% \n",
123088e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org         "Generate and install code",
12309dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org         generate_code_.InMillisecondsF(),
12310dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org         generate_code_.PercentOf(total));
12311068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  PrintF("----------------------------------------"
12312068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org         "---------------------------------------\n");
123131510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  PrintF("%32s %8.3f ms (%.1f times slower than full code gen)\n",
123148e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org         "Total",
12315dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org         total.InMillisecondsF(),
12316dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org         total.TimesOf(full_code_gen_));
123178e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
12318b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  double source_size_in_kb = static_cast<double>(source_size_) / 1024;
123197979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  double normalized_time =  source_size_in_kb > 0
12320dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org      ? total.InMillisecondsF() / source_size_in_kb
123217979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org      : 0;
123228e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  double normalized_size_in_kb = source_size_in_kb > 0
123238e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      ? total_size_ / 1024 / source_size_in_kb
123247979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org      : 0;
123251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  PrintF("%32s %8.3f ms           %7.3f kB allocated\n",
123268e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org         "Average per kB source",
123278e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org         normalized_time, normalized_size_in_kb);
12328a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
12329a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12330a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12331dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgvoid HStatistics::SaveTiming(const char* name, TimeDelta time, unsigned size) {
123321510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  total_size_ += size;
123331510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  for (int i = 0; i < names_.length(); ++i) {
123341510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    if (strcmp(names_[i], name) == 0) {
12335dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org      times_[i] += time;
123361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      sizes_[i] += size;
123371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      return;
12338a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
12339750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
123401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  names_.Add(name);
12341dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  times_.Add(time);
123421510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  sizes_.Add(size);
12343a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
12344a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12345a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12346750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgHPhase::~HPhase() {
123471510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (ShouldProduceTraceOutput()) {
123481510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
12349a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
12350a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12351a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifdef DEBUG
123521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  graph_->Verify(false);  // No full verify.
12353a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif
12354a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
12355a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12356a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} }  // namespace v8::internal
12357