1a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
4a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
6a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
7b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org#include "src/bailout-reason.h"
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/code-stubs.h"
9e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org#include "src/field-index.h"
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen.h"
11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/lithium.h"
12a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
13a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgnamespace v8 {
14a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgnamespace internal {
15a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
16a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
17068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.orgstatic LChunk* OptimizeGraph(HGraph* graph) {
1879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
1979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHandleAllocation no_handles;
2079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHandleDereference no_deref;
21068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org
22e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(graph != NULL);
23594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  BailoutReason bailout_reason = kNoReason;
24068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  if (!graph->Optimize(&bailout_reason)) {
25594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    FATAL(GetBailoutReason(bailout_reason));
26068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  }
27a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  LChunk* chunk = LChunk::NewChunk(graph);
28068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  if (chunk == NULL) {
29594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    FATAL(GetBailoutReason(graph->info()->bailout_reason()));
30068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  }
31068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  return chunk;
32a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
33a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
34a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
35a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass CodeStubGraphBuilderBase : public HGraphBuilder {
36a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org public:
37a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  CodeStubGraphBuilderBase(Isolate* isolate, HydrogenCodeStub* stub)
386e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org      : HGraphBuilder(&info_),
396e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org        arguments_length_(NULL),
406e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org        info_(stub, isolate),
41e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org        descriptor_(stub),
426e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org        context_(NULL) {
4342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org    int parameter_count = descriptor_.GetEnvironmentParameterCount();
4493720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    parameters_.Reset(new HParameter*[parameter_count]);
4509d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  }
46a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  virtual bool BuildGraph();
47a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
48a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org protected:
496e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  virtual HValue* BuildCodeStub() = 0;
506e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HParameter* GetParameter(int parameter) {
5142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org    DCHECK(parameter < descriptor_.GetEnvironmentParameterCount());
526e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    return parameters_[parameter];
536e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  }
546e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HValue* GetArgumentsLength() {
556e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    // This is initialized in BuildGraph()
56e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(arguments_length_ != NULL);
576e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    return arguments_length_;
586e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  }
5994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  CompilationInfo* info() { return &info_; }
60a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  HydrogenCodeStub* stub() { return info_.code_stub(); }
614cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  HContext* context() { return context_; }
6294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  Isolate* isolate() { return info_.isolate(); }
63a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
64f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  HLoadNamedField* BuildLoadNamedField(HValue* object,
65e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org                                       FieldIndex index);
669d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  void BuildStoreNamedField(HValue* object, HValue* value, FieldIndex index,
679d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org                            Representation representation);
68f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
69d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  enum ArgumentClass {
70d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    NONE,
71d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    SINGLE,
72d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    MULTIPLE
73d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  };
74d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
7506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  HValue* UnmappedCase(HValue* elements, HValue* key);
7606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org
77d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  HValue* BuildArrayConstructor(ElementsKind kind,
781510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                AllocationSiteOverrideMode override_mode,
79d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org                                ArgumentClass argument_class);
80d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  HValue* BuildInternalArrayConstructor(ElementsKind kind,
81d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org                                        ArgumentClass argument_class);
82d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
8397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  // BuildCheckAndInstallOptimizedCode emits code to install the optimized
8497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  // function found in the optimized code map at map_index in js_function, if
8597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  // the function at map_index matches the given native_context. Builder is
8697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  // left in the "Then()" state after the install.
8797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  void BuildCheckAndInstallOptimizedCode(HValue* js_function,
8897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org                                         HValue* native_context,
8997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org                                         IfBuilder* builder,
9097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org                                         HValue* optimized_map,
9197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org                                         HValue* map_index);
92662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  void BuildInstallCode(HValue* js_function, HValue* shared_info);
9397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
9497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  HInstruction* LoadFromOptimizedCodeMap(HValue* optimized_map,
9597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org                                         HValue* iterator,
9697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org                                         int field_offset);
97662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  void BuildInstallFromOptimizedCodeMap(HValue* js_function,
98662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org                                        HValue* shared_info,
99662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org                                        HValue* native_context);
100662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
101a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org private:
102d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder);
103d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder,
104d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org                                          ElementsKind kind);
105d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
106a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  SmartArrayPointer<HParameter*> parameters_;
1076e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HValue* arguments_length_;
108a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  CompilationInfoWithZone info_;
109e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  CodeStubDescriptor descriptor_;
1104cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  HContext* context_;
111a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org};
112a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
113a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
114a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgbool CodeStubGraphBuilderBase::BuildGraph() {
11577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  // Update the static counter each time a new code stub is generated.
11677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  isolate()->counters()->code_stubs()->Increment();
11777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
118fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  if (FLAG_trace_hydrogen_stubs) {
1197c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    const char* name = CodeStub::MajorName(stub()->MajorKey(), false);
120a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    PrintF("-----------------------------------------------------------\n");
1217c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    PrintF("Compiling stub %s using hydrogen\n", name);
122750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    isolate()->GetHTracer()->TraceCompilation(&info_);
123a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
124a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
12542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  int param_count = descriptor_.GetEnvironmentParameterCount();
1266e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HEnvironment* start_environment = graph()->start_environment();
127b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  HBasicBlock* next_block = CreateBasicBlock(start_environment);
12871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  Goto(next_block);
12909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  next_block->SetJoinId(BailoutId::StubEntry());
13009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  set_current_block(next_block);
13109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org
13242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  bool runtime_stack_params = descriptor_.stack_parameter_count().is_valid();
1330cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  HInstruction* stack_parameter_count = NULL;
13409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  for (int i = 0; i < param_count; ++i) {
13542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org    Representation r = descriptor_.GetEnvironmentParameterRepresentation(i);
13693720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    HParameter* param = Add<HParameter>(i,
13793720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org                                        HParameter::REGISTER_PARAMETER, r);
13809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    start_environment->Bind(i, param);
139a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    parameters_[i] = param;
14042ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org    if (descriptor_.IsEnvironmentParameterCountRegister(i)) {
1410cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org      param->set_type(HType::Smi());
1420cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org      stack_parameter_count = param;
1430cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org      arguments_length_ = stack_parameter_count;
1440cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org    }
145a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
14694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
147e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!runtime_stack_params || arguments_length_ != NULL);
1480cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  if (!runtime_stack_params) {
1496e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    stack_parameter_count = graph()->GetConstantMinus1();
1506e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    arguments_length_ = graph()->GetConstant0();
1516e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  }
1526e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
153db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org  context_ = Add<HContext>();
1546e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  start_environment->BindContext(context_);
15594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
156c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  Add<HSimulate>(BailoutId::StubEntry());
157a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
158e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  NoObservableSideEffectsScope no_effects(this);
159e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
1606e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  HValue* return_value = BuildCodeStub();
161f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
162f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  // We might have extra expressions to pop from the stack in addition to the
163a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  // arguments above.
164f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  HInstruction* stack_pop_count = stack_parameter_count;
16542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  if (descriptor_.function_mode() == JS_FUNCTION_STUB_MODE) {
166ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    if (!stack_parameter_count->IsConstant() &&
16742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org        descriptor_.hint_stack_parameter_count() < 0) {
1680cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org      HInstruction* constant_one = graph()->GetConstant1();
169f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      stack_pop_count = AddUncasted<HAdd>(stack_parameter_count, constant_one);
170ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      stack_pop_count->ClearFlag(HValue::kCanOverflow);
1710cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org      // TODO(mvstanton): verify that stack_parameter_count+1 really fits in a
1720cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org      // smi.
173ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    } else {
17442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org      int count = descriptor_.hint_stack_parameter_count();
175d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      stack_pop_count = Add<HConstant>(count);
176ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    }
177f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  }
178f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
179b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  if (current_block() != NULL) {
180d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    HReturn* hreturn_instruction = New<HReturn>(return_value,
181d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                                                stack_pop_count);
18271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org    FinishCurrentBlock(hreturn_instruction);
183ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
184a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  return true;
185a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
186a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
187f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
188a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgtemplate <class Stub>
189a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass CodeStubGraphBuilder: public CodeStubGraphBuilderBase {
190a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org public:
191ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  CodeStubGraphBuilder(Isolate* isolate, Stub* stub)
192e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org      : CodeStubGraphBuilderBase(isolate, stub) {}
193a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
194a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org protected:
19577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  virtual HValue* BuildCodeStub() {
196a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    if (casted_stub()->IsUninitialized()) {
19777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org      return BuildCodeUninitializedStub();
198a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    } else {
199a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      return BuildCodeInitializedStub();
20077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    }
20177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  }
20277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
20377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  virtual HValue* BuildCodeInitializedStub() {
20477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    UNIMPLEMENTED();
20577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    return NULL;
20677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  }
20777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
20877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  virtual HValue* BuildCodeUninitializedStub() {
20977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    // Force a deopt that falls back to the runtime.
21077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    HValue* undefined = graph()->GetConstantUndefined();
21132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    IfBuilder builder(this);
21232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    builder.IfNot<HCompareObjectEqAndBranch, HValue*>(undefined, undefined);
21332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    builder.Then();
214594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    builder.ElseDeopt("Forced deopt to runtime");
21577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    return undefined;
21677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  }
21777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
218a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  Stub* casted_stub() { return static_cast<Stub*>(stub()); }
219a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org};
220a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
221a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
222e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.orgHandle<Code> HydrogenCodeStub::GenerateLightweightMissCode(
223e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org    ExternalReference miss) {
224f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  Factory* factory = isolate()->factory();
22577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
22677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  // Generate the new code.
227f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  MacroAssembler masm(isolate(), NULL, 256);
22877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
22977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  {
23077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    // Update the static counter each time a new code stub is generated.
231f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    isolate()->counters()->code_stubs()->Increment();
23277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
23377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    // Generate the code for the stub.
23477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    masm.set_generating_stub(true);
23577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org    NoCurrentFrameScope scope(&masm);
236e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org    GenerateLightweightMiss(&masm, miss);
23777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  }
23877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
23977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  // Create the code object.
24077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  CodeDesc desc;
24177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  masm.GetCode(&desc);
24277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
24377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  // Copy the generated code into a heap object.
24477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  Code::Flags flags = Code::ComputeFlags(
24577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org      GetCodeKind(),
24677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org      GetICState(),
24777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org      GetExtraICState(),
248f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      GetStubType());
24977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  Handle<Code> new_object = factory->NewCode(
25077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org      desc, flags, masm.CodeObject(), NeedsImmovableCode());
25177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  return new_object;
25277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org}
25377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
25477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
2557bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgtemplate <class Stub>
256f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgstatic Handle<Code> DoGenerateCode(Stub* stub) {
257f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  Isolate* isolate = stub->isolate();
258e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  CodeStubDescriptor descriptor(stub);
259a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
260a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  // If we are uninitialized we can use a light-weight stub to enter
26177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  // the runtime that is significantly faster than using the standard
26277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  // stub-failure deopt mechanism.
26342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  if (stub->IsUninitialized() && descriptor.has_miss_handler()) {
26442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org    DCHECK(!descriptor.stack_parameter_count().is_valid());
265e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org    return stub->GenerateLightweightMissCode(descriptor.miss_handler());
26677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  }
2675de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  base::ElapsedTimer timer;
268d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  if (FLAG_profile_hydrogen_code_stub_compilation) {
269d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    timer.Start();
270d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  }
271e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org  CodeStubGraphBuilder<Stub> builder(isolate, stub);
272a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  LChunk* chunk = OptimizeGraph(builder.CreateGraph());
273f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org  // TODO(yangguo) remove this once the code serializer handles code stubs.
274f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org  if (FLAG_serialize_toplevel) chunk->info()->PrepareForSerializing();
275d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  Handle<Code> code = chunk->Codegen();
276d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  if (FLAG_profile_hydrogen_code_stub_compilation) {
277d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    OFStream os(stdout);
278d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    os << "[Lazy compilation of " << stub << " took "
279d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org       << timer.Elapsed().InMillisecondsF() << " ms]" << endl;
280d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  }
281d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  return code;
2827bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org}
2837bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
2847bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
285a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgtemplate <>
286c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgHValue* CodeStubGraphBuilder<ToNumberStub>::BuildCodeStub() {
287c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  HValue* value = GetParameter(0);
288c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
289c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // Check if the parameter is already a SMI or heap number.
290c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  IfBuilder if_number(this);
291c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if_number.If<HIsSmiAndBranch>(value);
292052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org  if_number.OrIf<HCompareMap>(value, isolate()->factory()->heap_number_map());
293c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if_number.Then();
294c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
295c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // Return the number.
296c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  Push(value);
297c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
298c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if_number.Else();
299c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
300c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // Convert the parameter to number using the builtin.
301d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HValue* function = AddLoadJSBuiltin(Builtins::TO_NUMBER);
3028d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  Add<HPushArguments>(value);
303d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  Push(Add<HInvokeFunction>(function, 1));
304c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
305c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if_number.End();
306c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
307c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  return Pop();
308c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
309c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
310c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
311f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Code> ToNumberStub::GenerateCode() {
312f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
313c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
314c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
315c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
316c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgtemplate <>
3173d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.orgHValue* CodeStubGraphBuilder<NumberToStringStub>::BuildCodeStub() {
3183d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  info()->MarkAsSavesCallerDoubles();
3193d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  HValue* number = GetParameter(NumberToStringStub::kNumber);
3206d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  return BuildNumberToString(number, Type::Number(zone()));
3213d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org}
3223d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org
3233d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org
324f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Code> NumberToStringStub::GenerateCode() {
325f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
3263d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org}
3273d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org
3283d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org
3293d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.orgtemplate <>
330e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgHValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() {
331e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Factory* factory = isolate()->factory();
33232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  HValue* undefined = graph()->GetConstantUndefined();
333e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  AllocationSiteMode alloc_site_mode = casted_stub()->allocation_site_mode();
334a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
335a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  // This stub is very performance sensitive, the generated code must be tuned
336a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  // so that it doesn't build and eager frame.
337a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  info()->MarkMustNotHaveEagerFrame();
338e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
339d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* allocation_site = Add<HLoadKeyed>(GetParameter(0),
340d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                                                  GetParameter(1),
341d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                                                  static_cast<HValue*>(NULL),
342d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                                                  FAST_ELEMENTS);
34332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  IfBuilder checker(this);
344d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site,
345d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                                                    undefined);
34632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  checker.Then();
347e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
348ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  HObjectAccess access = HObjectAccess::ForAllocationSiteOffset(
349ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org      AllocationSite::kTransitionInfoOffset);
35009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  HInstruction* boilerplate = Add<HLoadNamedField>(
35109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      allocation_site, static_cast<HValue*>(NULL), access);
352a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  HValue* elements = AddLoadElements(boilerplate);
353a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  HValue* capacity = AddLoadFixedArrayLength(elements);
354a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  IfBuilder zero_capacity(this);
355a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  zero_capacity.If<HCompareNumericAndBranch>(capacity, graph()->GetConstant0(),
356a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                           Token::EQ);
357a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  zero_capacity.Then();
358a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  Push(BuildCloneShallowArrayEmpty(boilerplate,
359a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                   allocation_site,
360a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                   alloc_site_mode));
361a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  zero_capacity.Else();
362a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  IfBuilder if_fixed_cow(this);
363a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  if_fixed_cow.If<HCompareMap>(elements, factory->fixed_cow_array_map());
364a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  if_fixed_cow.Then();
365a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  Push(BuildCloneShallowArrayCow(boilerplate,
366a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                 allocation_site,
367a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                 alloc_site_mode,
368a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                 FAST_ELEMENTS));
369a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  if_fixed_cow.Else();
370a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  IfBuilder if_fixed(this);
371a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  if_fixed.If<HCompareMap>(elements, factory->fixed_array_map());
372a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  if_fixed.Then();
373a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  Push(BuildCloneShallowArrayNonEmpty(boilerplate,
374a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                      allocation_site,
375a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                      alloc_site_mode,
376a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                      FAST_ELEMENTS));
377a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org
378a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  if_fixed.Else();
379a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  Push(BuildCloneShallowArrayNonEmpty(boilerplate,
380a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                      allocation_site,
381a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                      alloc_site_mode,
382a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org                                      FAST_DOUBLE_ELEMENTS));
383a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  if_fixed.End();
384a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  if_fixed_cow.End();
385a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  zero_capacity.End();
386e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
387594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  checker.ElseDeopt("Uninitialized boilerplate literals");
388c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  checker.End();
389c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
390c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  return environment()->Pop();
391e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
392e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
393e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
394f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Code> FastCloneShallowArrayStub::GenerateCode() {
395f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
396e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
397e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
398e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
399e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgtemplate <>
4006e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.orgHValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() {
40132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  HValue* undefined = graph()->GetConstantUndefined();
40271fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org
403dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  HInstruction* allocation_site = Add<HLoadKeyed>(GetParameter(0),
404dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org                                                  GetParameter(1),
405dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org                                                  static_cast<HValue*>(NULL),
406dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org                                                  FAST_ELEMENTS);
40771fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org
40832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  IfBuilder checker(this);
409dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site,
410d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                                                    undefined);
41132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  checker.And();
41271fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org
413ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  HObjectAccess access = HObjectAccess::ForAllocationSiteOffset(
414ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org      AllocationSite::kTransitionInfoOffset);
41509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  HInstruction* boilerplate = Add<HLoadNamedField>(
41609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      allocation_site, static_cast<HValue*>(NULL), access);
417dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org
41871fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org  int size = JSObject::kHeaderSize + casted_stub()->length() * kPointerSize;
419dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  int object_size = size;
420dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  if (FLAG_allocation_site_pretenuring) {
421dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org    size += AllocationMemento::kSize;
422dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  }
423dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org
42463ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org  HValue* boilerplate_map = Add<HLoadNamedField>(
42509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      boilerplate, static_cast<HValue*>(NULL),
42609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      HObjectAccess::ForMap());
42763ea3d20e0c5531a4bb0853218d5f746117edea1mvstanton@chromium.org  HValue* boilerplate_size = Add<HLoadNamedField>(
42809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      boilerplate_map, static_cast<HValue*>(NULL),
42909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      HObjectAccess::ForMapInstanceSize());
430dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  HValue* size_in_words = Add<HConstant>(object_size >> kPointerSizeLog2);
431e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  checker.If<HCompareNumericAndBranch>(boilerplate_size,
432e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org                                       size_in_words, Token::EQ);
43332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  checker.Then();
43471fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org
435d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HValue* size_in_bytes = Add<HConstant>(size);
436a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
437d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* object = Add<HAllocate>(size_in_bytes, HType::JSObject(),
43871ea97f146aa116d61baeba1912b87a60feda71fhpayer@chromium.org      NOT_TENURED, JS_OBJECT_TYPE);
43971fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org
440dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  for (int i = 0; i < object_size; i += kPointerSize) {
4410a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset(i);
44209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org    Add<HStoreNamedField>(
44309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org        object, access, Add<HLoadNamedField>(
4440a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org            boilerplate, static_cast<HValue*>(NULL), access));
44571fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org  }
44671fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org
447e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(FLAG_allocation_site_pretenuring || (size == object_size));
448dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  if (FLAG_allocation_site_pretenuring) {
449ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    BuildCreateAllocationMemento(
450ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org        object, Add<HConstant>(object_size), allocation_site);
451dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  }
452dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org
453c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  environment()->Push(object);
454594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  checker.ElseDeopt("Uninitialized boilerplate in fast clone");
455c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  checker.End();
456c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
457c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  return environment()->Pop();
45871fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org}
45971fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org
46071fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org
461f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Code> FastCloneShallowObjectStub::GenerateCode() {
462f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
46371fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org}
46471fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org
46571fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org
46671fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.orgtemplate <>
467bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgHValue* CodeStubGraphBuilder<CreateAllocationSiteStub>::BuildCodeStub() {
468d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HValue* size = Add<HConstant>(AllocationSite::kSize);
469d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* object = Add<HAllocate>(size, HType::JSObject(), TENURED,
470d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      JS_OBJECT_TYPE);
471bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
472bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  // Store the map
473528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Handle<Map> allocation_site_map = isolate()->factory()->allocation_site_map();
474bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  AddStoreMapConstant(object, allocation_site_map);
475bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
476bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  // Store the payload (smi elements kind)
477d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HValue* initial_elements_kind = Add<HConstant>(GetInitialFastElementsKind());
478ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  Add<HStoreNamedField>(object,
479ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org                        HObjectAccess::ForAllocationSiteOffset(
480ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org                            AllocationSite::kTransitionInfoOffset),
4810a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                        initial_elements_kind);
482ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
4833d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  // Unlike literals, constructed arrays don't have nested sites
4843d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  Add<HStoreNamedField>(object,
485ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org                        HObjectAccess::ForAllocationSiteOffset(
486ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org                            AllocationSite::kNestedSiteOffset),
4870a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                        graph()->GetConstant0());
4883d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org
4894ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org  // Pretenuring calculation field.
49090dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org  Add<HStoreNamedField>(object,
49190dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org                        HObjectAccess::ForAllocationSiteOffset(
4924ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org                            AllocationSite::kPretenureDataOffset),
4930a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                        graph()->GetConstant0());
49490dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org
4954ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org  // Pretenuring memento creation count field.
49690dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org  Add<HStoreNamedField>(object,
49790dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org                        HObjectAccess::ForAllocationSiteOffset(
4984ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org                            AllocationSite::kPretenureCreateCountOffset),
4990a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                        graph()->GetConstant0());
50090dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org
501528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // Store an empty fixed array for the code dependency.
502528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HConstant* empty_fixed_array =
503528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Add<HConstant>(isolate()->factory()->empty_fixed_array());
5046a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  Add<HStoreNamedField>(
505528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      object,
506ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org      HObjectAccess::ForAllocationSiteOffset(
507ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org          AllocationSite::kDependentCodeOffset),
5080a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      empty_fixed_array);
509528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
510d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // Link the object to the allocation site list
511d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HValue* site_list = Add<HConstant>(
512d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      ExternalReference::allocation_sites_list_address(isolate()));
51309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  HValue* site = Add<HLoadNamedField>(
51409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      site_list, static_cast<HValue*>(NULL),
51509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      HObjectAccess::ForAllocationSiteList());
5166a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  // TODO(mvstanton): This is a store to a weak pointer, which we may want to
5176a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  // mark as such in order to skip the write barrier, once we have a unified
5186a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  // system for weakness. For now we decided to keep it like this because having
5196a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  // an initial write barrier backed store makes this pointer strong until the
5206a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  // next GC, and allocation sites are designed to survive several GCs anyway.
5216a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  Add<HStoreNamedField>(
5226a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      object,
523ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org      HObjectAccess::ForAllocationSiteOffset(AllocationSite::kWeakNextOffset),
5240a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org      site);
525d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  Add<HStoreNamedField>(site_list, HObjectAccess::ForAllocationSiteList(),
5260a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                        object);
527bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
528f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  HInstruction* feedback_vector = GetParameter(0);
529f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  HInstruction* slot = GetParameter(1);
530f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  Add<HStoreKeyed>(feedback_vector, slot, object, FAST_ELEMENTS,
531f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                   INITIALIZING_STORE);
532f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  return feedback_vector;
533bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org}
534bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
535bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
536f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Code> CreateAllocationSiteStub::GenerateCode() {
537f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
538bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org}
539bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
540bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
541bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgtemplate <>
542dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgHValue* CodeStubGraphBuilder<LoadFastElementStub>::BuildCodeStub() {
543a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  HInstruction* load = BuildUncheckedMonomorphicElementAccess(
5449aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org      GetParameter(LoadDescriptor::kReceiverIndex),
5459aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org      GetParameter(LoadDescriptor::kNameIndex), NULL,
546fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      casted_stub()->is_js_array(), casted_stub()->elements_kind(), LOAD,
547fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      NEVER_RETURN_HOLE, STANDARD_STORE);
5486e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  return load;
549a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
550a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
551a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
552dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgHandle<Code> LoadFastElementStub::GenerateCode() {
553f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
5547bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org}
5557bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
5567bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
557f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgHLoadNamedField* CodeStubGraphBuilderBase::BuildLoadNamedField(
558e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org    HValue* object, FieldIndex index) {
559e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  Representation representation = index.is_double()
560e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      ? Representation::Double()
561e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      : Representation::Tagged();
562e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  int offset = index.offset();
563e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  HObjectAccess access = index.is_inobject()
564f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      ? HObjectAccess::ForObservableJSObjectOffset(offset, representation)
565f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      : HObjectAccess::ForBackingStoreOffset(offset, representation);
566e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  if (index.is_double()) {
567f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    // Load the heap number.
568f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    object = Add<HLoadNamedField>(
569f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        object, static_cast<HValue*>(NULL),
570f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        access.WithRepresentation(Representation::Tagged()));
571f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    // Load the double value from it.
572f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    access = HObjectAccess::ForHeapNumberValue();
573f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
574f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  return Add<HLoadNamedField>(object, static_cast<HValue*>(NULL), access);
575f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
576f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
577f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
57857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.orgtemplate<>
57957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.orgHValue* CodeStubGraphBuilder<LoadFieldStub>::BuildCodeStub() {
580e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  return BuildLoadNamedField(GetParameter(0), casted_stub()->index());
58157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org}
58257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
58357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
584f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Code> LoadFieldStub::GenerateCode() {
585f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
58657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org}
58757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
58857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
5899d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgtemplate <>
5909d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgHValue* CodeStubGraphBuilder<LoadConstantStub>::BuildCodeStub() {
5919d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  HValue* map = AddLoadMap(GetParameter(0), NULL);
5929d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  HObjectAccess descriptors_access = HObjectAccess::ForObservableJSObjectOffset(
5939d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      Map::kDescriptorsOffset, Representation::Tagged());
5949d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  HValue* descriptors =
5959d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      Add<HLoadNamedField>(map, static_cast<HValue*>(NULL), descriptors_access);
5969d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  HObjectAccess value_access = HObjectAccess::ForObservableJSObjectOffset(
597ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      DescriptorArray::GetValueOffset(casted_stub()->constant_index()));
5989d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  return Add<HLoadNamedField>(descriptors, static_cast<HValue*>(NULL),
5999d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org                              value_access);
6009d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org}
6019d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
6029d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
6039d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgHandle<Code> LoadConstantStub::GenerateCode() { return DoGenerateCode(this); }
6049d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
6059d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
60606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.orgHValue* CodeStubGraphBuilderBase::UnmappedCase(HValue* elements, HValue* key) {
60706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  HValue* result;
60806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  HInstruction* backing_store = Add<HLoadKeyed>(
60906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      elements, graph()->GetConstant1(), static_cast<HValue*>(NULL),
61006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      FAST_ELEMENTS, ALLOW_RETURN_HOLE);
61106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  Add<HCheckMaps>(backing_store, isolate()->factory()->fixed_array_map());
61206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  HValue* backing_store_length =
61306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      Add<HLoadNamedField>(backing_store, static_cast<HValue*>(NULL),
61406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org                           HObjectAccess::ForFixedArrayLength());
61506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  IfBuilder in_unmapped_range(this);
61606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  in_unmapped_range.If<HCompareNumericAndBranch>(key, backing_store_length,
61706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org                                                 Token::LT);
61806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  in_unmapped_range.Then();
61906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  {
62006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    result = Add<HLoadKeyed>(backing_store, key, static_cast<HValue*>(NULL),
62106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org                             FAST_HOLEY_ELEMENTS, NEVER_RETURN_HOLE);
62206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  }
62306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  in_unmapped_range.ElseDeopt("Outside of range");
62406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  in_unmapped_range.End();
62506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  return result;
62606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org}
62706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org
62806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org
62906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.orgtemplate <>
63006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.orgHValue* CodeStubGraphBuilder<KeyedLoadSloppyArgumentsStub>::BuildCodeStub() {
63106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex);
63206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  HValue* key = GetParameter(LoadDescriptor::kNameIndex);
63306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org
63406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  // Mapped arguments are actual arguments. Unmapped arguments are values added
63506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  // to the arguments object after it was created for the call. Mapped arguments
63606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  // are stored in the context at indexes given by elements[key + 2]. Unmapped
63706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  // arguments are stored as regular indexed properties in the arguments array,
63806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  // held at elements[1]. See NewSloppyArguments() in runtime.cc for a detailed
63906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  // look at argument object construction.
64006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  //
64106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  // The sloppy arguments elements array has a special format:
64206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  //
64306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  // 0: context
64406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  // 1: unmapped arguments array
64506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  // 2: mapped_index0,
64606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  // 3: mapped_index1,
64706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  // ...
64806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  //
64906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  // length is 2 + min(number_of_actual_arguments, number_of_formal_arguments).
65006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  // If key + 2 >= elements.length then attempt to look in the unmapped
65106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  // arguments array (given by elements[1]) and return the value at key, missing
65206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  // to the runtime if the unmapped arguments array is not a fixed array or if
65306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  // key >= unmapped_arguments_array.length.
65406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  //
65506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  // Otherwise, t = elements[key + 2]. If t is the hole, then look up the value
65606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  // in the unmapped arguments array, as described above. Otherwise, t is a Smi
65706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  // index into the context array given at elements[0]. Return the value at
65806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  // context[t].
65906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org
66006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  key = AddUncasted<HForceRepresentation>(key, Representation::Smi());
66106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  IfBuilder positive_smi(this);
66206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  positive_smi.If<HCompareNumericAndBranch>(key, graph()->GetConstant0(),
66306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org                                            Token::LT);
66406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  positive_smi.ThenDeopt("key is negative");
66506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  positive_smi.End();
66606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org
66706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  HValue* constant_two = Add<HConstant>(2);
66806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  HValue* elements = AddLoadElements(receiver, static_cast<HValue*>(NULL));
66906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  HValue* elements_length =
67006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      Add<HLoadNamedField>(elements, static_cast<HValue*>(NULL),
67106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org                           HObjectAccess::ForFixedArrayLength());
67206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  HValue* adjusted_length = AddUncasted<HSub>(elements_length, constant_two);
67306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  IfBuilder in_range(this);
67406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  in_range.If<HCompareNumericAndBranch>(key, adjusted_length, Token::LT);
67506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  in_range.Then();
67606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  {
67706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    HValue* index = AddUncasted<HAdd>(key, constant_two);
67806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    HInstruction* mapped_index =
67906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org        Add<HLoadKeyed>(elements, index, static_cast<HValue*>(NULL),
68006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org                        FAST_HOLEY_ELEMENTS, ALLOW_RETURN_HOLE);
68106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org
68206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    IfBuilder is_valid(this);
68306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    is_valid.IfNot<HCompareObjectEqAndBranch>(mapped_index,
68406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org                                              graph()->GetConstantHole());
68506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    is_valid.Then();
68606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    {
68706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      // TODO(mvstanton): I'd like to assert from this point, that if the
68806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      // mapped_index is not the hole that it is indeed, a smi. An unnecessary
68906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      // smi check is being emitted.
69006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      HValue* the_context =
69106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org          Add<HLoadKeyed>(elements, graph()->GetConstant0(),
69206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org                          static_cast<HValue*>(NULL), FAST_ELEMENTS);
69306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      DCHECK(Context::kHeaderSize == FixedArray::kHeaderSize);
69406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      HValue* result =
69506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org          Add<HLoadKeyed>(the_context, mapped_index, static_cast<HValue*>(NULL),
69606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org                          FAST_ELEMENTS, ALLOW_RETURN_HOLE);
69706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      environment()->Push(result);
69806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    }
69906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    is_valid.Else();
70006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    {
70106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      HValue* result = UnmappedCase(elements, key);
70206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      environment()->Push(result);
70306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    }
70406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    is_valid.End();
70506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  }
70606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  in_range.Else();
70706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  {
70806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    HValue* result = UnmappedCase(elements, key);
70906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    environment()->Push(result);
71006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  }
71106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  in_range.End();
71206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org
71306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  return environment()->Pop();
71406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org}
71506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org
71606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org
71706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.orgHandle<Code> KeyedLoadSloppyArgumentsStub::GenerateCode() {
71806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  return DoGenerateCode(this);
71906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org}
72006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org
72106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org
7229d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgvoid CodeStubGraphBuilderBase::BuildStoreNamedField(
7239d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    HValue* object, HValue* value, FieldIndex index,
7249d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    Representation representation) {
7259d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  DCHECK(!index.is_double() || representation.IsDouble());
7269d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  int offset = index.offset();
7279d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  HObjectAccess access =
7289d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      index.is_inobject()
7299d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org          ? HObjectAccess::ForObservableJSObjectOffset(offset, representation)
7309d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org          : HObjectAccess::ForBackingStoreOffset(offset, representation);
7319d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
7329d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  if (representation.IsDouble()) {
7339d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    // Load the heap number.
7349d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    object = Add<HLoadNamedField>(
7359d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org        object, static_cast<HValue*>(NULL),
7369d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org        access.WithRepresentation(Representation::Tagged()));
7379d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    // Store the double value into it.
7389d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    access = HObjectAccess::ForHeapNumberValue();
7399d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  } else if (representation.IsHeapObject()) {
7409d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    BuildCheckHeapObject(value);
7419d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  }
7429d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
7438640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  Add<HStoreNamedField>(object, access, value, INITIALIZING_STORE);
7449d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org}
7459d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
7469d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
7479d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgtemplate <>
7489d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgHValue* CodeStubGraphBuilder<StoreFieldStub>::BuildCodeStub() {
7499d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  BuildStoreNamedField(GetParameter(0), GetParameter(2), casted_stub()->index(),
7509d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org                       casted_stub()->representation());
7519d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  return GetParameter(2);
7529d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org}
7539d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
7549d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
7559d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgHandle<Code> StoreFieldStub::GenerateCode() { return DoGenerateCode(this); }
7569d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
7579d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
7589d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgtemplate <>
759381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.orgHValue* CodeStubGraphBuilder<StringLengthStub>::BuildCodeStub() {
760e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  HValue* string = BuildLoadNamedField(GetParameter(0),
761e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      FieldIndex::ForInObjectOffset(JSValue::kValueOffset));
762e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org  return BuildLoadNamedField(string,
763e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org      FieldIndex::ForInObjectOffset(String::kLengthOffset));
76457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org}
76557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
76657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
767f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Code> StringLengthStub::GenerateCode() {
768f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
76957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org}
77057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
77157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
7727bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgtemplate <>
773dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgHValue* CodeStubGraphBuilder<StoreFastElementStub>::BuildCodeStub() {
7747bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  BuildUncheckedMonomorphicElementAccess(
7759aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org      GetParameter(StoreDescriptor::kReceiverIndex),
7769aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org      GetParameter(StoreDescriptor::kNameIndex),
7779aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org      GetParameter(StoreDescriptor::kValueIndex), casted_stub()->is_js_array(),
778fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      casted_stub()->elements_kind(), STORE, NEVER_RETURN_HOLE,
779fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      casted_stub()->store_mode());
7807bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
7817bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  return GetParameter(2);
7827bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org}
7837bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
7847bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
785dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgHandle<Code> StoreFastElementStub::GenerateCode() {
786f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
787a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
788a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
789a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
79094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgtemplate <>
7916e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.orgHValue* CodeStubGraphBuilder<TransitionElementsKindStub>::BuildCodeStub() {
79294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  info()->MarkAsSavesCallerDoubles();
79394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
794ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  BuildTransitionElementsKind(GetParameter(0),
795ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                              GetParameter(1),
796ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                              casted_stub()->from_kind(),
797ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                              casted_stub()->to_kind(),
7989801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org                              casted_stub()->is_js_array());
799a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
800ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return GetParameter(0);
80194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org}
80294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
80394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
804f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Code> TransitionElementsKindStub::GenerateCode() {
805f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
8067bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org}
8077bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org
808d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgHValue* CodeStubGraphBuilderBase::BuildArrayConstructor(
8091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    ElementsKind kind,
8101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    AllocationSiteOverrideMode override_mode,
811d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    ArgumentClass argument_class) {
812d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  HValue* constructor = GetParameter(ArrayConstructorStubBase::kConstructor);
8136d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  HValue* alloc_site = GetParameter(ArrayConstructorStubBase::kAllocationSite);
814bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  JSArrayBuilder array_builder(this, kind, alloc_site, constructor,
8151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                               override_mode);
816d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  HValue* result = NULL;
817d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  switch (argument_class) {
818d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    case NONE:
819a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      // This stub is very performance sensitive, the generated code must be
820a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      // tuned so that it doesn't build and eager frame.
821a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      info()->MarkMustNotHaveEagerFrame();
822d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      result = array_builder.AllocateEmptyArray();
823d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      break;
824d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    case SINGLE:
825d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      result = BuildArraySingleArgumentConstructor(&array_builder);
826d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      break;
827d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    case MULTIPLE:
828d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      result = BuildArrayNArgumentsConstructor(&array_builder, kind);
829d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      break;
830d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  }
8311510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
832d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  return result;
8334a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
8344a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
8354a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
836d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgHValue* CodeStubGraphBuilderBase::BuildInternalArrayConstructor(
837d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    ElementsKind kind, ArgumentClass argument_class) {
838d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  HValue* constructor = GetParameter(
839d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      InternalArrayConstructorStubBase::kConstructor);
840d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  JSArrayBuilder array_builder(this, kind, constructor);
841d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
842d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  HValue* result = NULL;
843d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  switch (argument_class) {
844d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    case NONE:
845a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      // This stub is very performance sensitive, the generated code must be
846a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      // tuned so that it doesn't build and eager frame.
847a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org      info()->MarkMustNotHaveEagerFrame();
848d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      result = array_builder.AllocateEmptyArray();
849d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      break;
850d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    case SINGLE:
851d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      result = BuildArraySingleArgumentConstructor(&array_builder);
852d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      break;
853d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    case MULTIPLE:
854d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      result = BuildArrayNArgumentsConstructor(&array_builder, kind);
855d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      break;
856d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  }
857d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  return result;
8584a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
8594a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
8604a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
861d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgHValue* CodeStubGraphBuilderBase::BuildArraySingleArgumentConstructor(
862d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    JSArrayBuilder* array_builder) {
863ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // Smi check and range check on the input arg.
864ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  HValue* constant_one = graph()->GetConstant1();
865ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  HValue* constant_zero = graph()->GetConstant0();
866ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
867d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* elements = Add<HArgumentsElements>(false);
868db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org  HInstruction* argument = Add<HAccessArgumentsAt>(
869db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org      elements, constant_one, constant_zero);
870ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
871b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  return BuildAllocateArrayFromLength(array_builder, argument);
8724a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
8734a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
8744a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
875d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgHValue* CodeStubGraphBuilderBase::BuildArrayNArgumentsConstructor(
876d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    JSArrayBuilder* array_builder, ElementsKind kind) {
8779f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org  // Insert a bounds check because the number of arguments might exceed
8789f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org  // the kInitialMaxFastElementArray limit. This cannot happen for code
8799f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org  // that was parsed, but calling via Array.apply(thisArg, [...]) might
8809f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org  // trigger it.
8819f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org  HValue* length = GetArgumentsLength();
8829f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org  HConstant* max_alloc_length =
8839f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org      Add<HConstant>(JSObject::kInitialMaxFastElementArray);
8849f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org  HValue* checked_length = Add<HBoundsCheck>(length, max_alloc_length);
8859f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org
886ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // We need to fill with the hole if it's a smi array in the multi-argument
887ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // case because we might have to bail out while copying arguments into
888ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // the array because they aren't compatible with a smi array.
889ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // If it's a double array, no problem, and if it's fast then no
890ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // problem either because doubles are boxed.
891b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  //
892b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  // TODO(mvstanton): consider an instruction to memset fill the array
893b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  // with zero in this case instead.
894b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  JSArrayBuilder::FillMode fill_mode = IsFastSmiElementsKind(kind)
895b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      ? JSArrayBuilder::FILL_WITH_HOLE
896b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      : JSArrayBuilder::DONT_FILL_WITH_HOLE;
8979f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org  HValue* new_object = array_builder->AllocateArray(checked_length,
89838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                                                    max_alloc_length,
8999f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org                                                    checked_length,
900b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                                    fill_mode);
901d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  HValue* elements = array_builder->GetElementsLocation();
902e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(elements != NULL);
903ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
904ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  // Now populate the elements correctly.
905ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  LoopBuilder builder(this,
906ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org                      context(),
907ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org                      LoopBuilder::kPostIncrement);
908ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  HValue* start = graph()->GetConstant0();
9099f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org  HValue* key = builder.BeginBody(start, checked_length, Token::LT);
910d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HInstruction* argument_elements = Add<HArgumentsElements>(false);
911db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org  HInstruction* argument = Add<HAccessArgumentsAt>(
9129f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org      argument_elements, checked_length, key);
913ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
9140a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  Add<HStoreKeyed>(elements, key, argument, kind);
915ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  builder.EndBody();
916ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  return new_object;
9174a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
9184a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
9194a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
920d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgtemplate <>
921d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgHValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() {
922d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  ElementsKind kind = casted_stub()->elements_kind();
9231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  AllocationSiteOverrideMode override_mode = casted_stub()->override_mode();
924034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  return BuildArrayConstructor(kind, override_mode, NONE);
925d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org}
926d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
927d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
928f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Code> ArrayNoArgumentConstructorStub::GenerateCode() {
929f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
930d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org}
931d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
932d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
933d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgtemplate <>
934d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgHValue* CodeStubGraphBuilder<ArraySingleArgumentConstructorStub>::
935d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    BuildCodeStub() {
936d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  ElementsKind kind = casted_stub()->elements_kind();
9371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  AllocationSiteOverrideMode override_mode = casted_stub()->override_mode();
938034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  return BuildArrayConstructor(kind, override_mode, SINGLE);
939d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org}
940d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
941d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
942f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Code> ArraySingleArgumentConstructorStub::GenerateCode() {
943f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
944d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org}
945d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
946d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
947d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgtemplate <>
948d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgHValue* CodeStubGraphBuilder<ArrayNArgumentsConstructorStub>::BuildCodeStub() {
949d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  ElementsKind kind = casted_stub()->elements_kind();
9501510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  AllocationSiteOverrideMode override_mode = casted_stub()->override_mode();
951034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  return BuildArrayConstructor(kind, override_mode, MULTIPLE);
952d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org}
953d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
954d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
955f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Code> ArrayNArgumentsConstructorStub::GenerateCode() {
956f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
9574a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
9584a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
959ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
960ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgtemplate <>
961d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgHValue* CodeStubGraphBuilder<InternalArrayNoArgumentConstructorStub>::
962d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    BuildCodeStub() {
963d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  ElementsKind kind = casted_stub()->elements_kind();
964d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  return BuildInternalArrayConstructor(kind, NONE);
965d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org}
966d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
967d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
968f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Code> InternalArrayNoArgumentConstructorStub::GenerateCode() {
969f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
970d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org}
971d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
972d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
973d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgtemplate <>
974d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgHValue* CodeStubGraphBuilder<InternalArraySingleArgumentConstructorStub>::
975d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    BuildCodeStub() {
976d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  ElementsKind kind = casted_stub()->elements_kind();
977d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  return BuildInternalArrayConstructor(kind, SINGLE);
978d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org}
979d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
980d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
981f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Code> InternalArraySingleArgumentConstructorStub::GenerateCode() {
982f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
983d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org}
984d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
985d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
986d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgtemplate <>
987d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgHValue* CodeStubGraphBuilder<InternalArrayNArgumentsConstructorStub>::
988d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    BuildCodeStub() {
989d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  ElementsKind kind = casted_stub()->elements_kind();
990d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  return BuildInternalArrayConstructor(kind, MULTIPLE);
991d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org}
992d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
993d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
994f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Code> InternalArrayNArgumentsConstructorStub::GenerateCode() {
995f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
996d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org}
997d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
998d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
999d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgtemplate <>
1000a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.orgHValue* CodeStubGraphBuilder<CompareNilICStub>::BuildCodeInitializedStub() {
100141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  Isolate* isolate = graph()->isolate();
1002ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  CompareNilICStub* stub = casted_stub();
1003ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  HIfContinuation continuation;
100441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  Handle<Map> sentinel_map(isolate->heap()->meta_map());
10056d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  Type* type = stub->GetType(zone(), sentinel_map);
100671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  BuildCompareNil(GetParameter(0), type, &continuation);
1007ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  IfBuilder if_nil(this, &continuation);
1008ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  if_nil.Then();
1009ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  if (continuation.IsFalseReachable()) {
1010ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    if_nil.Else();
101153ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org    if_nil.Return(graph()->GetConstant0());
1012ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
1013ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  if_nil.End();
1014ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  return continuation.IsTrueReachable()
101553ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org      ? graph()->GetConstant1()
1016ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      : graph()->GetConstantUndefined();
1017ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
1018ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
1019ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
1020f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Code> CompareNilICStub::GenerateCode() {
1021f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
1022ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
1023ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
1024b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org
1025b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.orgtemplate <>
1026ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.orgHValue* CodeStubGraphBuilder<BinaryOpICStub>::BuildCodeInitializedStub() {
1027d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org  BinaryOpICState state = casted_stub()->state();
102825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
1029ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org  HValue* left = GetParameter(BinaryOpICStub::kLeft);
1030ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org  HValue* right = GetParameter(BinaryOpICStub::kRight);
1031ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org
10326d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  Type* left_type = state.GetLeftType(zone());
10336d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  Type* right_type = state.GetRightType(zone());
10346d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  Type* result_type = state.GetResultType(zone());
103525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
1036e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!left_type->Is(Type::None()) && !right_type->Is(Type::None()) &&
1037ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org         (state.HasSideEffects() || !result_type->Is(Type::None())));
103825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
103925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  HValue* result = NULL;
10400f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HAllocationMode allocation_mode(NOT_TENURED);
1041ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org  if (state.op() == Token::ADD &&
104225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      (left_type->Maybe(Type::String()) || right_type->Maybe(Type::String())) &&
104325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      !left_type->Is(Type::String()) && !right_type->Is(Type::String())) {
1044e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org    // For the generic add stub a fast case for string addition is performance
104525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    // critical.
104625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    if (left_type->Maybe(Type::String())) {
1047e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      IfBuilder if_leftisstring(this);
1048e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      if_leftisstring.If<HIsStringAndBranch>(left);
1049e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      if_leftisstring.Then();
1050e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      {
10517ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org        Push(BuildBinaryOperation(
1052ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org                    state.op(), left, right,
10536d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org                    Type::String(zone()), right_type,
10540f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                    result_type, state.fixed_right_arg(),
10550f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                    allocation_mode));
1056e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      }
1057e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      if_leftisstring.Else();
1058e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      {
10597ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org        Push(BuildBinaryOperation(
1060ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org                    state.op(), left, right,
1061e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org                    left_type, right_type, result_type,
10620f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                    state.fixed_right_arg(), allocation_mode));
1063e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      }
1064e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      if_leftisstring.End();
106525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      result = Pop();
106625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    } else {
1067e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      IfBuilder if_rightisstring(this);
1068e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      if_rightisstring.If<HIsStringAndBranch>(right);
1069e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      if_rightisstring.Then();
1070e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      {
10717ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org        Push(BuildBinaryOperation(
1072ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org                    state.op(), left, right,
10736d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org                    left_type, Type::String(zone()),
10740f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                    result_type, state.fixed_right_arg(),
10750f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                    allocation_mode));
1076e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      }
1077e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      if_rightisstring.Else();
1078e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      {
10797ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org        Push(BuildBinaryOperation(
1080ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org                    state.op(), left, right,
1081e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org                    left_type, right_type, result_type,
10820f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                    state.fixed_right_arg(), allocation_mode));
1083e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      }
1084e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org      if_rightisstring.End();
108525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      result = Pop();
108625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    }
108725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  } else {
10887ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org    result = BuildBinaryOperation(
1089ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org            state.op(), left, right,
1090e7a07450b06d405206bf210de0aa6bbb440ab9a7bmeurer@chromium.org            left_type, right_type, result_type,
10910f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org            state.fixed_right_arg(), allocation_mode);
109225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  }
109325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
109425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  // If we encounter a generic argument, the number conversion is
109525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  // observable, thus we cannot afford to bail out after the fact.
1096ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org  if (!state.HasSideEffects()) {
109725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    result = EnforceNumberType(result, result_type);
109825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  }
109925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
1100a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  // Reuse the double box of one of the operands if we are allowed to (i.e.
1101a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  // chained binops).
1102ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org  if (state.CanReuseDoubleBox()) {
1103ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    HValue* operand = (state.mode() == OVERWRITE_LEFT) ? left : right;
110425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    IfBuilder if_heap_number(this);
11058f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    if_heap_number.If<HHasInstanceTypeAndBranch>(operand, HEAP_NUMBER_TYPE);
110625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    if_heap_number.Then();
11070a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    Add<HStoreNamedField>(operand, HObjectAccess::ForHeapNumberValue(), result);
1108a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    Push(operand);
110925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    if_heap_number.Else();
111025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    Push(result);
111125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    if_heap_number.End();
111225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    result = Pop();
111325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  }
111425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
111525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  return result;
111625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org}
111725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
111825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
1119f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Code> BinaryOpICStub::GenerateCode() {
1120f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
112125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org}
112225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
112325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
112425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.orgtemplate <>
11250f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.orgHValue* CodeStubGraphBuilder<BinaryOpWithAllocationSiteStub>::BuildCodeStub() {
1126d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org  BinaryOpICState state = casted_stub()->state();
11270f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
11280f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HValue* allocation_site = GetParameter(
11290f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org      BinaryOpWithAllocationSiteStub::kAllocationSite);
11300f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HValue* left = GetParameter(BinaryOpWithAllocationSiteStub::kLeft);
11310f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HValue* right = GetParameter(BinaryOpWithAllocationSiteStub::kRight);
11320f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
11336d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  Type* left_type = state.GetLeftType(zone());
11346d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  Type* right_type = state.GetRightType(zone());
11356d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  Type* result_type = state.GetResultType(zone());
11360f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  HAllocationMode allocation_mode(allocation_site);
11370f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
11380f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  return BuildBinaryOperation(state.op(), left, right,
11390f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                              left_type, right_type, result_type,
11400f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org                              state.fixed_right_arg(), allocation_mode);
11410f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org}
11420f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
11430f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
1144f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Code> BinaryOpWithAllocationSiteStub::GenerateCode() {
1145f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
11460f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org}
11470f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
11480f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org
11490f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.orgtemplate <>
1150bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.orgHValue* CodeStubGraphBuilder<StringAddStub>::BuildCodeInitializedStub() {
1151bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org  StringAddStub* stub = casted_stub();
11520cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  StringAddFlags flags = stub->flags();
11530cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  PretenureFlag pretenure_flag = stub->pretenure_flag();
11540cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
1155bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org  HValue* left = GetParameter(StringAddStub::kLeft);
1156bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org  HValue* right = GetParameter(StringAddStub::kRight);
11570cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
11580cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  // Make sure that both arguments are strings if not known in advance.
11590cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  if ((flags & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT) {
116090dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org    left = BuildCheckString(left);
11610cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  }
11620cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  if ((flags & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT) {
116390dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org    right = BuildCheckString(right);
11640cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  }
11650cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
11660f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org  return BuildStringAdd(left, right, HAllocationMode(pretenure_flag));
11670cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org}
11680cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
11690cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
1170f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Code> StringAddStub::GenerateCode() {
1171f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
11720cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org}
11730cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
11740cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
11750cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.orgtemplate <>
1176b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.orgHValue* CodeStubGraphBuilder<ToBooleanStub>::BuildCodeInitializedStub() {
1177b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  ToBooleanStub* stub = casted_stub();
11788640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  HValue* true_value = NULL;
11798640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  HValue* false_value = NULL;
11808640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
1181c714f377950c6a8a80b90ddca93ad8bd23ce362amachenbach@chromium.org  switch (stub->mode()) {
11828640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    case ToBooleanStub::RESULT_AS_SMI:
11838640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      true_value = graph()->GetConstant1();
11848640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      false_value = graph()->GetConstant0();
11858640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      break;
11868640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    case ToBooleanStub::RESULT_AS_ODDBALL:
11878640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      true_value = graph()->GetConstantTrue();
11888640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      false_value = graph()->GetConstantFalse();
11898640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      break;
11908640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    case ToBooleanStub::RESULT_AS_INVERSE_ODDBALL:
11918640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      true_value = graph()->GetConstantFalse();
11928640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      false_value = graph()->GetConstantTrue();
11938640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      break;
11948640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  }
1195b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org
1196b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  IfBuilder if_true(this);
1197c714f377950c6a8a80b90ddca93ad8bd23ce362amachenbach@chromium.org  if_true.If<HBranch>(GetParameter(0), stub->types());
1198b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  if_true.Then();
11998640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  if_true.Return(true_value);
1200b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  if_true.Else();
1201b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  if_true.End();
12028640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  return false_value;
1203b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org}
1204b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org
1205b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org
1206f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Code> ToBooleanStub::GenerateCode() {
1207f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
1208b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org}
1209b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org
1210b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org
1211e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.orgtemplate <>
1212e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.orgHValue* CodeStubGraphBuilder<StoreGlobalStub>::BuildCodeInitializedStub() {
1213e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  StoreGlobalStub* stub = casted_stub();
1214e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  Handle<Object> placeholer_value(Smi::FromInt(0), isolate());
1215e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  Handle<PropertyCell> placeholder_cell =
1216e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org      isolate()->factory()->NewPropertyCell(placeholer_value);
1217e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
12189aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  HParameter* value = GetParameter(StoreDescriptor::kValueIndex);
1219e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
1220bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  if (stub->check_global()) {
1221bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org    // Check that the map of the global has not changed: use a placeholder map
1222bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org    // that will be replaced later with the global object's map.
1223bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org    Handle<Map> placeholder_map = isolate()->factory()->meta_map();
1224bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org    HValue* global = Add<HConstant>(
1225bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org        StoreGlobalStub::global_placeholder(isolate()));
1226af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org    Add<HCheckMaps>(global, placeholder_map);
1227bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  }
1228e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
1229d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HValue* cell = Add<HConstant>(placeholder_cell);
1230c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  HObjectAccess access(HObjectAccess::ForCellPayload(isolate()));
123109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  HValue* cell_contents = Add<HLoadNamedField>(
123209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      cell, static_cast<HValue*>(NULL), access);
1233e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
1234c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if (stub->is_constant()) {
1235c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    IfBuilder builder(this);
1236c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    builder.If<HCompareObjectEqAndBranch>(cell_contents, value);
1237c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    builder.Then();
1238594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    builder.ElseDeopt("Unexpected cell contents in constant global store");
1239c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    builder.End();
1240c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  } else {
1241e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    // Load the payload of the global parameter cell. A hole indicates that the
1242e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    // property has been deleted and that the store must be handled by the
1243e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    // runtime.
1244e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    IfBuilder builder(this);
124506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    HValue* hole_value = graph()->GetConstantHole();
1246e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    builder.If<HCompareObjectEqAndBranch>(cell_contents, hole_value);
1247e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    builder.Then();
1248594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    builder.Deopt("Unexpected cell contents in global store");
1249e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    builder.Else();
12500a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org    Add<HStoreNamedField>(cell, access, value);
1251e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org    builder.End();
1252e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  }
1253c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
1254e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  return value;
1255e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org}
1256e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
1257e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
1258f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Code> StoreGlobalStub::GenerateCode() {
1259f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
1260e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org}
1261e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
1262e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
1263ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgtemplate<>
1264ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgHValue* CodeStubGraphBuilder<ElementsTransitionAndStoreStub>::BuildCodeStub() {
1265d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org  HValue* value = GetParameter(ElementsTransitionAndStoreStub::kValueIndex);
1266d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org  HValue* map = GetParameter(ElementsTransitionAndStoreStub::kMapIndex);
1267d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org  HValue* key = GetParameter(ElementsTransitionAndStoreStub::kKeyIndex);
1268d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org  HValue* object = GetParameter(ElementsTransitionAndStoreStub::kObjectIndex);
1269ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1270ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  if (FLAG_trace_elements_transitions) {
1271ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    // Tracing elements transitions is the job of the runtime.
12723d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    Add<HDeoptimize>("Tracing elements transitions", Deoptimizer::EAGER);
1273ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  } else {
1274ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    info()->MarkAsSavesCallerDoubles();
1275ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1276ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    BuildTransitionElementsKind(object, map,
1277ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                casted_stub()->from_kind(),
1278ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                casted_stub()->to_kind(),
1279ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                casted_stub()->is_jsarray());
1280ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
12811e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org    BuildUncheckedMonomorphicElementAccess(object, key, value,
12821e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org                                           casted_stub()->is_jsarray(),
12831e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org                                           casted_stub()->to_kind(),
1284f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                                           STORE, ALLOW_RETURN_HOLE,
12851e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org                                           casted_stub()->store_mode());
1286ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  }
1287ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1288ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  return value;
1289ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org}
1290ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1291ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1292f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Code> ElementsTransitionAndStoreStub::GenerateCode() {
1293f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
1294ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org}
1295ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
1296ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
129797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.orgvoid CodeStubGraphBuilderBase::BuildCheckAndInstallOptimizedCode(
1298662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    HValue* js_function,
1299662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    HValue* native_context,
130097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    IfBuilder* builder,
130197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    HValue* optimized_map,
130297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    HValue* map_index) {
130397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  HValue* osr_ast_id_none = Add<HConstant>(BailoutId::None().ToInt());
130497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  HValue* context_slot = LoadFromOptimizedCodeMap(
130597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      optimized_map, map_index, SharedFunctionInfo::kContextOffset);
130697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  HValue* osr_ast_slot = LoadFromOptimizedCodeMap(
130797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      optimized_map, map_index, SharedFunctionInfo::kOsrAstIdOffset);
130897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  builder->If<HCompareObjectEqAndBranch>(native_context,
130997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org                                         context_slot);
131097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  builder->AndIf<HCompareObjectEqAndBranch>(osr_ast_slot, osr_ast_id_none);
131197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  builder->Then();
131297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  HValue* code_object = LoadFromOptimizedCodeMap(optimized_map,
131397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      map_index, SharedFunctionInfo::kCachedCodeOffset);
131497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  // and the literals
131597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  HValue* literals = LoadFromOptimizedCodeMap(optimized_map,
131697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      map_index, SharedFunctionInfo::kLiteralsOffset);
131797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
1318662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  Counters* counters = isolate()->counters();
1319528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  AddIncrementCounter(counters->fast_new_closure_install_optimized());
1320662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
1321662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  // TODO(fschneider): Idea: store proper code pointers in the optimized code
1322662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  // map and either unmangle them on marking or do nothing as the whole map is
1323662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  // discarded on major GC anyway.
1324662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  Add<HStoreCodeEntry>(js_function, code_object);
132597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(),
132697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org                        literals);
1327662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
1328662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  // Now link a function into a list of optimized functions.
132909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  HValue* optimized_functions_list = Add<HLoadNamedField>(
133009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      native_context, static_cast<HValue*>(NULL),
1331662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org      HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST));
1332662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  Add<HStoreNamedField>(js_function,
1333662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org                        HObjectAccess::ForNextFunctionLinkPointer(),
13340a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                        optimized_functions_list);
1335662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
1336662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  // This store is the only one that should have a write barrier.
1337662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  Add<HStoreNamedField>(native_context,
1338662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org           HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST),
13390a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org           js_function);
134097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
134197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  // The builder continues in the "then" after this function.
1342662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org}
1343662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
1344662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
1345662436e7b124b3535773535c671c53db322070b5verwaest@chromium.orgvoid CodeStubGraphBuilderBase::BuildInstallCode(HValue* js_function,
1346662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org                                                HValue* shared_info) {
1347662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  Add<HStoreNamedField>(js_function,
1348662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org                        HObjectAccess::ForNextFunctionLinkPointer(),
13490a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                        graph()->GetConstantUndefined());
135009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  HValue* code_object = Add<HLoadNamedField>(
135109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      shared_info, static_cast<HValue*>(NULL), HObjectAccess::ForCodeOffset());
1352662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  Add<HStoreCodeEntry>(js_function, code_object);
1353662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org}
1354662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
1355662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
135697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.orgHInstruction* CodeStubGraphBuilderBase::LoadFromOptimizedCodeMap(
135797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    HValue* optimized_map,
135897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    HValue* iterator,
135997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    int field_offset) {
136097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  // By making sure to express these loads in the form [<hvalue> + constant]
136197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  // the keyed load can be hoisted.
1362e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(field_offset >= 0 && field_offset < SharedFunctionInfo::kEntryLength);
136397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  HValue* field_slot = iterator;
136497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  if (field_offset > 0) {
136597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    HValue* field_offset_value = Add<HConstant>(field_offset);
136697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    field_slot = AddUncasted<HAdd>(iterator, field_offset_value);
136797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  }
136897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  HInstruction* field_entry = Add<HLoadKeyed>(optimized_map, field_slot,
136997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      static_cast<HValue*>(NULL), FAST_ELEMENTS);
137097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  return field_entry;
137197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org}
137297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
137397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
1374662436e7b124b3535773535c671c53db322070b5verwaest@chromium.orgvoid CodeStubGraphBuilderBase::BuildInstallFromOptimizedCodeMap(
1375662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    HValue* js_function,
1376662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    HValue* shared_info,
1377662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    HValue* native_context) {
1378662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  Counters* counters = isolate()->counters();
1379662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  IfBuilder is_optimized(this);
138009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  HInstruction* optimized_map = Add<HLoadNamedField>(
138109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      shared_info, static_cast<HValue*>(NULL),
1382662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org      HObjectAccess::ForOptimizedCodeMap());
1383662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  HValue* null_constant = Add<HConstant>(0);
1384662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  is_optimized.If<HCompareObjectEqAndBranch>(optimized_map, null_constant);
1385662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  is_optimized.Then();
1386662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  {
1387662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    BuildInstallCode(js_function, shared_info);
1388662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  }
1389662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  is_optimized.Else();
1390662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  {
1391528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    AddIncrementCounter(counters->fast_new_closure_try_optimized());
1392662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    // optimized_map points to fixed array of 3-element entries
1393662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    // (native context, optimized code, literals).
1394662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    // Map must never be empty, so check the first elements.
139597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    HValue* first_entry_index =
139697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org        Add<HConstant>(SharedFunctionInfo::kEntriesStart);
1397662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    IfBuilder already_in(this);
139897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    BuildCheckAndInstallOptimizedCode(js_function, native_context, &already_in,
139997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org                                      optimized_map, first_entry_index);
1400662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    already_in.Else();
1401662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    {
140297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      // Iterate through the rest of map backwards. Do not double check first
140397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      // entry. After the loop, if no matching optimized code was found,
140497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      // install unoptimized code.
140597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      // for(i = map.length() - SharedFunctionInfo::kEntryLength;
140697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      //     i > SharedFunctionInfo::kEntriesStart;
140797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      //     i -= SharedFunctionInfo::kEntryLength) { .. }
1408662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org      HValue* shared_function_entry_length =
1409662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org          Add<HConstant>(SharedFunctionInfo::kEntryLength);
1410662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org      LoopBuilder loop_builder(this,
1411662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org                               context(),
1412662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org                               LoopBuilder::kPostDecrement,
1413662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org                               shared_function_entry_length);
141409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      HValue* array_length = Add<HLoadNamedField>(
141509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org          optimized_map, static_cast<HValue*>(NULL),
1416662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org          HObjectAccess::ForFixedArrayLength());
141797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      HValue* start_pos = AddUncasted<HSub>(array_length,
141897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org                                            shared_function_entry_length);
141997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      HValue* slot_iterator = loop_builder.BeginBody(start_pos,
142097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org                                                     first_entry_index,
142197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org                                                     Token::GT);
1422662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org      {
142397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org        IfBuilder done_check(this);
142497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org        BuildCheckAndInstallOptimizedCode(js_function, native_context,
142597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org                                          &done_check,
142697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org                                          optimized_map,
142797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org                                          slot_iterator);
142897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org        // Fall out of the loop
142997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org        loop_builder.Break();
1430662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org      }
1431662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org      loop_builder.EndBody();
143297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
143397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      // If slot_iterator equals first entry index, then we failed to find and
143497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      // install optimized code
143597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      IfBuilder no_optimized_code_check(this);
143697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      no_optimized_code_check.If<HCompareNumericAndBranch>(
143797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org          slot_iterator, first_entry_index, Token::EQ);
143897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      no_optimized_code_check.Then();
143997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      {
144097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org        // Store the unoptimized code
144197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org        BuildInstallCode(js_function, shared_info);
144297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      }
1443662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    }
1444662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  }
1445662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org}
1446662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
1447662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
1448662436e7b124b3535773535c671c53db322070b5verwaest@chromium.orgtemplate<>
1449662436e7b124b3535773535c671c53db322070b5verwaest@chromium.orgHValue* CodeStubGraphBuilder<FastNewClosureStub>::BuildCodeStub() {
1450662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  Counters* counters = isolate()->counters();
1451662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  Factory* factory = isolate()->factory();
1452662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  HInstruction* empty_fixed_array =
1453662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org      Add<HConstant>(factory->empty_fixed_array());
1454662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  HValue* shared_info = GetParameter(0);
1455662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
1456528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  AddIncrementCounter(counters->fast_new_closure_total());
1457528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
1458662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  // Create a new closure from the given function info in new space
1459662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  HValue* size = Add<HConstant>(JSFunction::kSize);
1460662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  HInstruction* js_function = Add<HAllocate>(size, HType::JSObject(),
1461662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org                                             NOT_TENURED, JS_FUNCTION_TYPE);
1462662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
1463486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  int map_index = Context::FunctionMapIndex(casted_stub()->strict_mode(),
14642c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                                            casted_stub()->kind());
1465662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
1466662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  // Compute the function map in the current native context and set that
1467662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  // as the map of the allocated object.
1468662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  HInstruction* native_context = BuildGetNativeContext();
146909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  HInstruction* map_slot_value = Add<HLoadNamedField>(
147009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      native_context, static_cast<HValue*>(NULL),
1471662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org      HObjectAccess::ForContextSlot(map_index));
14720a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  Add<HStoreNamedField>(js_function, HObjectAccess::ForMap(), map_slot_value);
1473662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
1474662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  // Initialize the rest of the function.
1475662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  Add<HStoreNamedField>(js_function, HObjectAccess::ForPropertiesPointer(),
14760a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                        empty_fixed_array);
1477662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  Add<HStoreNamedField>(js_function, HObjectAccess::ForElementsPointer(),
14780a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                        empty_fixed_array);
1479662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(),
14800a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                        empty_fixed_array);
1481662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  Add<HStoreNamedField>(js_function, HObjectAccess::ForPrototypeOrInitialMap(),
14820a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                        graph()->GetConstantHole());
1483662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  Add<HStoreNamedField>(js_function,
1484662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org                        HObjectAccess::ForSharedFunctionInfoPointer(),
14850a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                        shared_info);
1486662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  Add<HStoreNamedField>(js_function, HObjectAccess::ForFunctionContextPointer(),
14870a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                        context());
1488662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
1489662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  // Initialize the code pointer in the function to be the one
1490662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  // found in the shared function info object.
1491662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  // But first check if there is an optimized version for our context.
1492662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  if (FLAG_cache_optimized_code) {
1493662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    BuildInstallFromOptimizedCodeMap(js_function, shared_info, native_context);
1494662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  } else {
1495662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    BuildInstallCode(js_function, shared_info);
1496662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  }
1497662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
1498662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  return js_function;
1499662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org}
1500662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
1501662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
1502f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Code> FastNewClosureStub::GenerateCode() {
1503f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
1504662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org}
1505662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
1506662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
1507ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgtemplate<>
1508bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.orgHValue* CodeStubGraphBuilder<FastNewContextStub>::BuildCodeStub() {
1509bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org  int length = casted_stub()->slots() + Context::MIN_CONTEXT_SLOTS;
1510bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org
1511bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org  // Get the function.
1512bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org  HParameter* function = GetParameter(FastNewContextStub::kFunction);
1513bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org
1514bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org  // Allocate the context in new space.
1515bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org  HAllocate* function_context = Add<HAllocate>(
1516bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org      Add<HConstant>(length * kPointerSize + FixedArray::kHeaderSize),
1517eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org      HType::HeapObject(), NOT_TENURED, FIXED_ARRAY_TYPE);
1518bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org
1519bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org  // Set up the object header.
1520bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org  AddStoreMapConstant(function_context,
1521bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org                      isolate()->factory()->function_context_map());
1522bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org  Add<HStoreNamedField>(function_context,
1523bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org                        HObjectAccess::ForFixedArrayLength(),
15240a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                        Add<HConstant>(length));
1525bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org
1526bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org  // Set up the fixed slots.
1527bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org  Add<HStoreNamedField>(function_context,
1528bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org                        HObjectAccess::ForContextSlot(Context::CLOSURE_INDEX),
15290a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                        function);
1530bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org  Add<HStoreNamedField>(function_context,
1531bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org                        HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX),
15320a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                        context());
1533bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org  Add<HStoreNamedField>(function_context,
1534bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org                        HObjectAccess::ForContextSlot(Context::EXTENSION_INDEX),
15350a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                        graph()->GetConstant0());
1536bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org
1537bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org  // Copy the global object from the previous context.
1538bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org  HValue* global_object = Add<HLoadNamedField>(
153909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      context(), static_cast<HValue*>(NULL),
154009cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org      HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
1541bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org  Add<HStoreNamedField>(function_context,
1542bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org                        HObjectAccess::ForContextSlot(
1543bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org                            Context::GLOBAL_OBJECT_INDEX),
15440a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                        global_object);
1545bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org
1546bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org  // Initialize the rest of the slots to undefined.
1547bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org  for (int i = Context::MIN_CONTEXT_SLOTS; i < length; ++i) {
1548bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org    Add<HStoreNamedField>(function_context,
1549bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org                          HObjectAccess::ForContextSlot(i),
15500a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                          graph()->GetConstantUndefined());
1551bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org  }
1552bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org
1553bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org  return function_context;
1554bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org}
1555bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org
1556bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org
1557f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Code> FastNewContextStub::GenerateCode() {
1558f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
1559bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org}
1560bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org
1561bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org
1562dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgtemplate <>
1563dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgHValue* CodeStubGraphBuilder<LoadDictionaryElementStub>::BuildCodeStub() {
15649aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex);
15659aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  HValue* key = GetParameter(LoadDescriptor::kNameIndex);
1566ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1567ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  Add<HCheckSmi>(key);
1568ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
15691845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* elements = AddLoadElements(receiver);
15701845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
15711845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* hash = BuildElementIndexHash(key);
15721845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
15731845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  return BuildUncheckedDictionaryElementLoad(receiver, elements, key, hash);
1574ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org}
1575ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1576ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1577dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgHandle<Code> LoadDictionaryElementStub::GenerateCode() {
1578f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
1579ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org}
1580ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
1581ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
158209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.orgtemplate<>
158309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.orgHValue* CodeStubGraphBuilder<RegExpConstructResultStub>::BuildCodeStub() {
158409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  // Determine the parameters.
158509cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  HValue* length = GetParameter(RegExpConstructResultStub::kLength);
158609cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  HValue* index = GetParameter(RegExpConstructResultStub::kIndex);
158709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  HValue* input = GetParameter(RegExpConstructResultStub::kInput);
158809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
1589874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org  info()->MarkMustNotHaveEagerFrame();
1590874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org
159109cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org  return BuildRegExpConstructResult(length, index, input);
159209cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org}
159309cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
159409cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
1595f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.orgHandle<Code> RegExpConstructResultStub::GenerateCode() {
1596f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  return DoGenerateCode(this);
159709cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org}
159809cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
159909cae8d7af4e66e8d0088c19dcd0033042fa8a6bmachenbach@chromium.org
16001845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgtemplate <>
1601dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgclass CodeStubGraphBuilder<KeyedLoadGenericStub>
1602dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    : public CodeStubGraphBuilderBase {
16031845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org public:
1604dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  CodeStubGraphBuilder(Isolate* isolate, KeyedLoadGenericStub* stub)
1605dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      : CodeStubGraphBuilderBase(isolate, stub) {}
16061845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
16071845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org protected:
16081845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  virtual HValue* BuildCodeStub();
16091845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
16101845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  void BuildElementsKindLimitCheck(HGraphBuilder::IfBuilder* if_builder,
16111845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                   HValue* bit_field2,
16121845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                   ElementsKind kind);
16131845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
16141845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  void BuildFastElementLoad(HGraphBuilder::IfBuilder* if_builder,
16151845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                            HValue* receiver,
16161845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                            HValue* key,
16171845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                            HValue* instance_type,
16181845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                            HValue* bit_field2,
16191845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                            ElementsKind kind);
16201845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
16211845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  void BuildExternalElementLoad(HGraphBuilder::IfBuilder* if_builder,
16221845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                HValue* receiver,
16231845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                HValue* key,
16241845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                HValue* instance_type,
16251845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                HValue* bit_field2,
16261845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                ElementsKind kind);
16271845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
1628dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  KeyedLoadGenericStub* casted_stub() {
1629dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    return static_cast<KeyedLoadGenericStub*>(stub());
16301845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  }
16311845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org};
16321845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
16331845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
1634dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildElementsKindLimitCheck(
1635dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    HGraphBuilder::IfBuilder* if_builder, HValue* bit_field2,
16361845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    ElementsKind kind) {
16371845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  ElementsKind next_kind = static_cast<ElementsKind>(kind + 1);
16381845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HValue* kind_limit = Add<HConstant>(
16391845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      static_cast<int>(Map::ElementsKindBits::encode(next_kind)));
16401845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
16411845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  if_builder->If<HCompareNumericAndBranch>(bit_field2, kind_limit, Token::LT);
16421845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  if_builder->Then();
16431845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org}
16441845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
16451845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
1646dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildFastElementLoad(
1647dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    HGraphBuilder::IfBuilder* if_builder, HValue* receiver, HValue* key,
1648dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    HValue* instance_type, HValue* bit_field2, ElementsKind kind) {
1649e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!IsExternalArrayElementsKind(kind));
16501845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
16511845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  BuildElementsKindLimitCheck(if_builder, bit_field2, kind);
16521845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
16531845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  IfBuilder js_array_check(this);
16541845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  js_array_check.If<HCompareNumericAndBranch>(
16551845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      instance_type, Add<HConstant>(JS_ARRAY_TYPE), Token::EQ);
16561845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  js_array_check.Then();
16571845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  Push(BuildUncheckedMonomorphicElementAccess(receiver, key, NULL,
16581845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                              true, kind,
16591845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                              LOAD, NEVER_RETURN_HOLE,
16601845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                              STANDARD_STORE));
16611845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  js_array_check.Else();
16621845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  Push(BuildUncheckedMonomorphicElementAccess(receiver, key, NULL,
16631845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                              false, kind,
16641845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                              LOAD, NEVER_RETURN_HOLE,
16651845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                              STANDARD_STORE));
16661845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  js_array_check.End();
16671845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org}
16681845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
16691845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
1670dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgvoid CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildExternalElementLoad(
1671dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    HGraphBuilder::IfBuilder* if_builder, HValue* receiver, HValue* key,
1672dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    HValue* instance_type, HValue* bit_field2, ElementsKind kind) {
1673e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsExternalArrayElementsKind(kind));
16741845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
16751845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  BuildElementsKindLimitCheck(if_builder, bit_field2, kind);
16761845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
16771845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  Push(BuildUncheckedMonomorphicElementAccess(receiver, key, NULL,
16781845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                              false, kind,
16791845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                              LOAD, NEVER_RETURN_HOLE,
16801845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                              STANDARD_STORE));
16811845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org}
16821845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
16831845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
1684dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgHValue* CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildCodeStub() {
16859aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex);
16869aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  HValue* key = GetParameter(LoadDescriptor::kNameIndex);
16871845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
16881845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  // Split into a smi/integer case and unique string case.
16891845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  HIfContinuation index_name_split_continuation(graph()->CreateBasicBlock(),
16901845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                                graph()->CreateBasicBlock());
16911845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
16921845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  BuildKeyedIndexCheck(key, &index_name_split_continuation);
16931845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
16941845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  IfBuilder index_name_split(this, &index_name_split_continuation);
16951845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  index_name_split.Then();
16961845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  {
16971845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    // Key is an index (number)
16981845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    key = Pop();
16991845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
17001845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    int bit_field_mask = (1 << Map::kIsAccessCheckNeeded) |
17011845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      (1 << Map::kHasIndexedInterceptor);
17021845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    BuildJSObjectCheck(receiver, bit_field_mask);
17031845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
17041845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    HValue* map = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL),
17051845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                       HObjectAccess::ForMap());
17061845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
17071845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    HValue* instance_type =
17081845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      Add<HLoadNamedField>(map, static_cast<HValue*>(NULL),
17091845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                           HObjectAccess::ForMapInstanceType());
17101845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
17111845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    HValue* bit_field2 = Add<HLoadNamedField>(map,
17121845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                              static_cast<HValue*>(NULL),
17131845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                              HObjectAccess::ForMapBitField2());
17141845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
17151845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    IfBuilder kind_if(this);
17161845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    BuildFastElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
17171845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                         FAST_HOLEY_ELEMENTS);
17181845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
17191845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    kind_if.Else();
17201845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    {
17211845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      BuildFastElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
17221845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                           FAST_HOLEY_DOUBLE_ELEMENTS);
17231845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    }
17241845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    kind_if.Else();
17251845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
17261845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    // The DICTIONARY_ELEMENTS check generates a "kind_if.Then"
17271845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    BuildElementsKindLimitCheck(&kind_if, bit_field2, DICTIONARY_ELEMENTS);
17281845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    {
17291845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      HValue* elements = AddLoadElements(receiver);
17301845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
17311845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      HValue* hash = BuildElementIndexHash(key);
17321845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
17331845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      Push(BuildUncheckedDictionaryElementLoad(receiver, elements, key, hash));
17341845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    }
17351845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    kind_if.Else();
17361845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
17371845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    // The SLOPPY_ARGUMENTS_ELEMENTS check generates a "kind_if.Then"
17381845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    BuildElementsKindLimitCheck(&kind_if, bit_field2,
17391845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                SLOPPY_ARGUMENTS_ELEMENTS);
17401845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    // Non-strict elements are not handled.
1741dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    Add<HDeoptimize>("non-strict elements in KeyedLoadGenericStub",
17421845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                     Deoptimizer::EAGER);
17431845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    Push(graph()->GetConstant0());
17441845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
17451845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    kind_if.Else();
17461845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
17471845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                             EXTERNAL_INT8_ELEMENTS);
17481845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
17491845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    kind_if.Else();
17501845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
17511845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                             EXTERNAL_UINT8_ELEMENTS);
17521845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
17531845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    kind_if.Else();
17541845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
17551845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                             EXTERNAL_INT16_ELEMENTS);
17561845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
17571845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    kind_if.Else();
17581845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
17591845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                             EXTERNAL_UINT16_ELEMENTS);
17601845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
17611845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    kind_if.Else();
17621845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
17631845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                             EXTERNAL_INT32_ELEMENTS);
17641845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
17651845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    kind_if.Else();
17661845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
17671845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                             EXTERNAL_UINT32_ELEMENTS);
17681845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
17691845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    kind_if.Else();
17701845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
17711845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                             EXTERNAL_FLOAT32_ELEMENTS);
17721845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
17731845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    kind_if.Else();
17741845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
17751845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                             EXTERNAL_FLOAT64_ELEMENTS);
17761845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
17771845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    kind_if.Else();
17781845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
17791845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                             EXTERNAL_UINT8_CLAMPED_ELEMENTS);
17801845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
1781dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org    kind_if.ElseDeopt("ElementsKind unhandled in KeyedLoadGenericStub");
17821845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
17831845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    kind_if.End();
17841845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  }
17851845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  index_name_split.Else();
17861845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  {
17871845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    // Key is a unique string.
17881845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    key = Pop();
17891845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
17901845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    int bit_field_mask = (1 << Map::kIsAccessCheckNeeded) |
17911845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        (1 << Map::kHasNamedInterceptor);
17921845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    BuildJSObjectCheck(receiver, bit_field_mask);
17931845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
17941845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    HIfContinuation continuation;
17951845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    BuildTestForDictionaryProperties(receiver, &continuation);
17961845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    IfBuilder if_dict_properties(this, &continuation);
17971845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    if_dict_properties.Then();
17981845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    {
17991845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      //  Key is string, properties are dictionary mode
18001845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      BuildNonGlobalObjectCheck(receiver);
18011845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
18021845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      HValue* properties = Add<HLoadNamedField>(
18031845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org          receiver, static_cast<HValue*>(NULL),
18041845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org          HObjectAccess::ForPropertiesPointer());
18051845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
18061845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      HValue* hash =
18071845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org          Add<HLoadNamedField>(key, static_cast<HValue*>(NULL),
18081845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org          HObjectAccess::ForNameHashField());
18091845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
1810d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      hash = AddUncasted<HShr>(hash, Add<HConstant>(Name::kHashShift));
1811d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
18121845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      HValue* value = BuildUncheckedDictionaryElementLoad(receiver,
18131845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                                          properties,
18141845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                                          key,
18151845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                                          hash);
18161845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      Push(value);
18171845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    }
18181845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    if_dict_properties.Else();
18191845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    {
18201845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      //  Key is string, properties are fast mode
18211845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      HValue* hash = BuildKeyedLookupCacheHash(receiver, key);
18221845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
18231845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      ExternalReference cache_keys_ref =
18241845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org          ExternalReference::keyed_lookup_cache_keys(isolate());
18251845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      HValue* cache_keys = Add<HConstant>(cache_keys_ref);
18261845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
18271845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      HValue* map = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL),
18281845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org                                         HObjectAccess::ForMap());
18291845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      HValue* base_index = AddUncasted<HMul>(hash, Add<HConstant>(2));
18301845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      base_index->ClearFlag(HValue::kCanOverflow);
18311845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
1832f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      HIfContinuation inline_or_runtime_continuation(
1833f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          graph()->CreateBasicBlock(), graph()->CreateBasicBlock());
1834f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      {
1835f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        IfBuilder lookup_ifs[KeyedLookupCache::kEntriesPerBucket];
1836f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        for (int probe = 0; probe < KeyedLookupCache::kEntriesPerBucket;
1837f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org             ++probe) {
1838f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          IfBuilder* lookup_if = &lookup_ifs[probe];
1839f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          lookup_if->Initialize(this);
1840f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          int probe_base = probe * KeyedLookupCache::kEntryLength;
1841f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          HValue* map_index = AddUncasted<HAdd>(
1842f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org              base_index,
1843f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org              Add<HConstant>(probe_base + KeyedLookupCache::kMapIndex));
1844f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          map_index->ClearFlag(HValue::kCanOverflow);
1845f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          HValue* key_index = AddUncasted<HAdd>(
1846f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org              base_index,
1847f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org              Add<HConstant>(probe_base + KeyedLookupCache::kKeyIndex));
1848f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          key_index->ClearFlag(HValue::kCanOverflow);
1849f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          HValue* map_to_check =
1850f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org              Add<HLoadKeyed>(cache_keys, map_index, static_cast<HValue*>(NULL),
1851f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org                              FAST_ELEMENTS, NEVER_RETURN_HOLE, 0);
1852f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          lookup_if->If<HCompareObjectEqAndBranch>(map_to_check, map);
1853f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          lookup_if->And();
1854f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          HValue* key_to_check =
1855f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org              Add<HLoadKeyed>(cache_keys, key_index, static_cast<HValue*>(NULL),
1856f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org                              FAST_ELEMENTS, NEVER_RETURN_HOLE, 0);
1857f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          lookup_if->If<HCompareObjectEqAndBranch>(key_to_check, key);
1858f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          lookup_if->Then();
1859f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          {
1860f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org            ExternalReference cache_field_offsets_ref =
1861f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org                ExternalReference::keyed_lookup_cache_field_offsets(isolate());
1862f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org            HValue* cache_field_offsets =
1863f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org                Add<HConstant>(cache_field_offsets_ref);
1864f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org            HValue* index = AddUncasted<HAdd>(hash, Add<HConstant>(probe));
1865f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org            index->ClearFlag(HValue::kCanOverflow);
1866f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org            HValue* property_index = Add<HLoadKeyed>(
1867f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org                cache_field_offsets, index, static_cast<HValue*>(NULL),
1868f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org                EXTERNAL_INT32_ELEMENTS, NEVER_RETURN_HOLE, 0);
1869f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org            Push(property_index);
1870f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          }
1871f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          lookup_if->Else();
1872f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        }
1873f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        for (int i = 0; i < KeyedLookupCache::kEntriesPerBucket; ++i) {
1874f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          lookup_ifs[i].JoinContinuation(&inline_or_runtime_continuation);
18751845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org        }
18761845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org      }
1877f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org
1878f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      IfBuilder inline_or_runtime(this, &inline_or_runtime_continuation);
1879f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      inline_or_runtime.Then();
1880f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      {
1881f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        // Found a cached index, load property inline.
1882f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        Push(Add<HLoadFieldByIndex>(receiver, Pop()));
1883f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      }
1884f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      inline_or_runtime.Else();
1885f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      {
1886f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        // KeyedLookupCache miss; call runtime.
1887f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        Add<HPushArguments>(receiver, key);
1888f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        Push(Add<HCallRuntime>(
1889f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org            isolate()->factory()->empty_string(),
1890f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org            Runtime::FunctionForId(Runtime::kKeyedGetProperty), 2));
1891f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      }
1892f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      inline_or_runtime.End();
18931845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    }
18941845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org    if_dict_properties.End();
18951845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  }
18961845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  index_name_split.End();
18971845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
18981845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  return Pop();
18991845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org}
19001845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
19011845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
1902dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgHandle<Code> KeyedLoadGenericStub::GenerateCode() {
19031845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  return DoGenerateCode(this);
19041845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org}
19051845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
19061845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
1907fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.orgtemplate <>
1908fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.orgHValue* CodeStubGraphBuilder<VectorLoadStub>::BuildCodeStub() {
19099aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex);
1910fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  Add<HDeoptimize>("Always deopt", Deoptimizer::EAGER);
1911fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  return receiver;
1912fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org}
1913fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org
1914fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org
1915fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.orgHandle<Code> VectorLoadStub::GenerateCode() { return DoGenerateCode(this); }
1916fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org
1917fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org
1918fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.orgtemplate <>
1919fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.orgHValue* CodeStubGraphBuilder<VectorKeyedLoadStub>::BuildCodeStub() {
19209aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex);
1921fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  Add<HDeoptimize>("Always deopt", Deoptimizer::EAGER);
1922fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  return receiver;
1923fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org}
1924fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org
1925fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org
1926fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.orgHandle<Code> VectorKeyedLoadStub::GenerateCode() {
1927fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  return DoGenerateCode(this);
1928fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org}
1929e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org
1930e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org
1931e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.orgHandle<Code> MegamorphicLoadStub::GenerateCode() {
1932e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  return DoGenerateCode(this);
1933e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org}
1934e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org
1935e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org
1936e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.orgtemplate <>
1937e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.orgHValue* CodeStubGraphBuilder<MegamorphicLoadStub>::BuildCodeStub() {
1938e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  // The return address is on the stack.
1939e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex);
1940e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  HValue* name = GetParameter(LoadDescriptor::kNameIndex);
1941e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org
1942e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  // Probe the stub cache.
1943e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
1944e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org      Code::ComputeHandlerFlags(Code::LOAD_IC));
1945e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  Add<HTailCallThroughMegamorphicCache>(receiver, name, flags);
1946e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org
1947e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  // We never continue.
1948e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  return graph()->GetConstant0();
1949e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org}
1950a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} }  // namespace v8::internal
1951