1f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Copyright 2012 the V8 project authors. All rights reserved.
2a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Redistribution and use in source and binary forms, with or without
3a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// modification, are permitted provided that the following conditions are
4a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// met:
5a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//
6a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//     * Redistributions of source code must retain the above copyright
7a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       notice, this list of conditions and the following disclaimer.
8a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//     * Redistributions in binary form must reproduce the above
9a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       copyright notice, this list of conditions and the following
10a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       disclaimer in the documentation and/or other materials provided
11a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       with the distribution.
12a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//     * Neither the name of Google Inc. nor the names of its
13a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       contributors may be used to endorse or promote products derived
14a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//       from this software without specific prior written permission.
15a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//
16a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
28a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifndef V8_X64_LITHIUM_CODEGEN_X64_H_
29a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#define V8_X64_LITHIUM_CODEGEN_X64_H_
30a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
31a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "x64/lithium-x64.h"
32a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
33c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org#include "checks.h"
34a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "deoptimizer.h"
35d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org#include "lithium-codegen.h"
36a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "safepoint-table.h"
37a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "scopes.h"
38b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org#include "v8utils.h"
390ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org#include "x64/lithium-gap-resolver-x64.h"
40a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
41a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace v8 {
42a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace internal {
43a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
44a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Forward declarations.
45a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass LDeferredCode;
46c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgclass SafepointGenerator;
47c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
48d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgclass LCodeGen: public LCodeGenBase {
49a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
505a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
51d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org      : LCodeGenBase(chunk, assembler, info),
525a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        deoptimizations_(4, info->zone()),
535a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        jump_table_(4, info->zone()),
545a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        deoptimization_literals_(8, info->zone()),
55c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org        inlined_function_count_(0),
568f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org        scope_(info->scope()),
575a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        translations_(info->zone()),
585a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        deferred_(8, info->zone()),
590ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org        osr_pc_offset_(-1),
60a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        frame_is_built_(false),
615a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        safepoints_(info->zone()),
6244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org        resolver_(this),
6371f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org        expected_safepoint_kind_(Safepoint::kSimple) {
64c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    PopulateDeoptimizationLiteralsWithInlinedFunctions();
65c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  }
66a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  int LookupDestination(int block_id) const {
6832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    return chunk()->LookupDestination(block_id);
6932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  }
7032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org
7132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  bool IsNextEmittedBlock(int block_id) const {
7232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    return LookupDestination(block_id) == GetNextEmittedBlock();
7332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  }
7432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org
75a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  bool NeedsEagerFrame() const {
76a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return GetStackSlotCount() > 0 ||
77a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        info()->is_non_deferred_calling() ||
7877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org        !info()->IsStub() ||
7977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org        info()->requires_frame();
80a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
81a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  bool NeedsDeferredFrame() const {
82a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    return !NeedsEagerFrame() && info()->is_deferred_calling();
83a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
84a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
850ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  // Support for converting LOperands to assembler types.
860ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  Register ToRegister(LOperand* op) const;
870ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  XMMRegister ToDoubleRegister(LOperand* op) const;
880ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  bool IsInteger32Constant(LConstantOperand* op) const;
89a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  bool IsSmiConstant(LConstantOperand* op) const;
90fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  int32_t ToInteger32(LConstantOperand* op) const;
91c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  Smi* ToSmi(LConstantOperand* op) const;
92394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  double ToDouble(LConstantOperand* op) const;
93d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  ExternalReference ToExternalReference(LConstantOperand* op) const;
940ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  bool IsTaggedConstant(LConstantOperand* op) const;
950ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  Handle<Object> ToHandle(LConstantOperand* op) const;
960ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  Operand ToOperand(LOperand* op) const;
970ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org
98a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Try to generate code for the entire chunk, but it may fail if the
99a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // chunk contains constructs we cannot handle. Returns true if the
100a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // code generation attempt succeeded.
101c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  bool GenerateCode();
102a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
103a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Finish the code by setting stack height, safepoint, and bailout
104a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // information on it.
105c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void FinishCode(Handle<Code> code);
106c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
107c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // Deferred code support.
108c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void DoDeferredNumberTagD(LNumberTagD* instr);
10946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  void DoDeferredNumberTagU(LNumberTagU* instr);
110c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  void DoDeferredTaggedToI(LTaggedToI* instr, Label* done);
111e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr);
11204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  void DoDeferredStackCheck(LStackCheck* instr);
1133a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
114b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
11594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  void DoDeferredAllocate(LAllocate* instr);
11627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
11727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                                       Label* map_check);
118594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void DoDeferredInstanceMigration(LCheckMaps* instr, Register object);
119f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
120f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Parallel move support.
121c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void DoParallelMove(LParallelMove* move);
1228e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  void DoGap(LGap* instr);
123c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
124c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // Emit frame translation commands for an environment.
125b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  void WriteTranslation(LEnvironment* environment, Translation* translation);
126c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
127c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // Declare methods that deal with the individual node types.
128c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org#define DECLARE_DO(type) void Do##type(L##type* node);
129c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
130c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org#undef DECLARE_DO
131c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
132c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org private:
133394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  StrictModeFlag strict_mode_flag() const {
1341b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    return info()->is_classic_mode() ? kNonStrictMode : kStrictMode;
1353a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
1363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
13728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  LPlatformChunk* chunk() const { return chunk_; }
138c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  Scope* scope() const { return scope_; }
13932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  HGraph* graph() const { return chunk()->graph(); }
140c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
141528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  XMMRegister double_scratch0() const { return xmm0; }
142528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
143c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void EmitClassOfTest(Label* if_true,
144c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                       Label* if_false,
145c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                       Handle<String> class_name,
146c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                       Register input,
147c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                       Register temporary,
148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                       Register scratch);
149c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
150160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
151c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
152594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void Abort(BailoutReason reason);
153c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
1547028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
155c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
156f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
157f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  void SaveCallerDoubles();
158f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  void RestoreCallerDoubles();
159f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
160c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // Code generation passes.  Returns true if code generation should
161c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // continue.
162c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  bool GeneratePrologue();
163c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  bool GenerateDeferredCode();
1649ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  bool GenerateJumpTable();
165c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  bool GenerateSafepointTable();
166c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
167c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  // Generates the custom OSR entrypoint and sets the osr_pc_offset.
168c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  void GenerateOsrPrologue();
169c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
17044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  enum SafepointMode {
17144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    RECORD_SIMPLE_SAFEPOINT,
17244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    RECORD_SAFEPOINT_WITH_REGISTERS
17344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  };
17444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
17544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  void CallCodeGeneric(Handle<Code> code,
17644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org                       RelocInfo::Mode mode,
17744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org                       LInstruction* instr,
17844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org                       SafepointMode safepoint_mode,
17944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org                       int argc);
18044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
18144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
182c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void CallCode(Handle<Code> code,
183c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                RelocInfo::Mode mode,
184c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                LInstruction* instr);
18544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
186ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  void CallRuntime(const Runtime::Function* function,
187c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                   int num_arguments,
188fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                   LInstruction* instr,
189fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                   SaveFPRegsMode save_doubles = kDontSaveFPRegs);
19044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
191c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void CallRuntime(Runtime::FunctionId id,
192c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                   int num_arguments,
193c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                   LInstruction* instr) {
194ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    const Runtime::Function* function = Runtime::FunctionForId(id);
195c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    CallRuntime(function, num_arguments, instr);
196c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  }
197c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
19844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  void CallRuntimeFromDeferred(Runtime::FunctionId id,
19944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org                               int argc,
200935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org                               LInstruction* instr,
201935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org                               LOperand* context);
202935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org
203935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  void LoadContextFromDeferred(LOperand* context);
20444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
205fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org  enum RDIState {
206fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org    RDI_UNINITIALIZED,
207fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org    RDI_CONTAINS_TARGET
208fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org  };
209fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org
210c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // Generate a direct call to a known function.  Expects the function
211394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // to be in rdi.
212c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void CallKnownFunction(Handle<JSFunction> function,
21332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                         int formal_parameter_count,
214c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                         int arity,
21540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                         LInstruction* instr,
216fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                         CallKind call_kind,
217fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                         RDIState rdi_state);
218c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
21927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  void RecordSafepointWithLazyDeopt(LInstruction* instr,
22027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                                    SafepointMode safepoint_mode,
22127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                                    int argc);
22227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  void RegisterEnvironmentForDeoptimization(LEnvironment* environment,
22327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                                            Safepoint::DeoptMode mode);
224aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org  void DeoptimizeIf(Condition cc,
225aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org                    LEnvironment* environment,
226aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org                    Deoptimizer::BailoutType bailout_type);
227c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void DeoptimizeIf(Condition cc, LEnvironment* environment);
228fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  void ApplyCheckIf(Condition cc, LBoundsCheck* check);
229594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
230935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  bool DeoptEveryNTimes() {
231935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org    return FLAG_deopt_every_n_times != 0 && !info()->IsStub();
232935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  }
233935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org
234594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void AddToTranslation(LEnvironment* environment,
235594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                        Translation* translation,
236c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                        LOperand* op,
23746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org                        bool is_tagged,
238594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                        bool is_uint32,
239594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                        int* object_index_pointer,
240594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                        int* dematerialized_index_pointer);
241c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void PopulateDeoptimizationData(Handle<Code> code);
242c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  int DefineDeoptimizationLiteral(Handle<Object> literal);
243c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
244c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void PopulateDeoptimizationLiteralsWithInlinedFunctions();
245c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
246c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  Register ToRegister(int index) const;
247c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  XMMRegister ToDoubleRegister(int index) const;
248717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  Operand BuildFastArrayOperand(
249b645116853c677aca8a316381b87441ba6004f67danno@chromium.org      LOperand* elements_pointer,
2506d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org      LOperand* key,
25183e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org      ElementsKind elements_kind,
2520e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org      uint32_t offset,
2530e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org      uint32_t additional_index = 0);
254c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
255e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  Operand BuildSeqStringOperand(Register string,
256e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                                LOperand* index,
257e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                                String::Encoding encoding);
258e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
259e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  void EmitIntegerMathAbs(LMathAbs* instr);
260594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void EmitSmiMathAbs(LMathAbs* instr);
261c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
262c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // Support for recording safepoint and position information.
263378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  void RecordSafepoint(LPointerMap* pointers,
264378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org                       Safepoint::Kind kind,
265378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org                       int arguments,
26627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                       Safepoint::DeoptMode mode);
26727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode);
26827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  void RecordSafepoint(Safepoint::DeoptMode mode);
269c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void RecordSafepointWithRegisters(LPointerMap* pointers,
270c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                                    int arguments,
27127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                                    Safepoint::DeoptMode mode);
27271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  void RecordAndWritePosition(int position) V8_OVERRIDE;
273c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
274c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  static Condition TokenToCondition(Token::Value op, bool is_unsigned);
27504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  void EmitGoto(int block);
2760cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
2770cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  // EmitBranch expects to be the last instruction of a block.
2781510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  template<class InstrType>
2791510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  void EmitBranch(InstrType instr, Condition cc);
280c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  template<class InstrType>
281c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  void EmitFalseBranch(InstrType instr, Condition cc);
28294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  void EmitNumberUntagD(
28394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      Register input,
28494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      XMMRegister result,
285b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org      bool allow_undefined_as_nan,
28694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      bool deoptimize_on_minus_zero,
28794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      LEnvironment* env,
28894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org      NumberUntagDMode mode = NUMBER_CANDIDATE_IS_ANY_TAGGED);
289c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
290c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // Emits optimized code for typeof x == "y".  Modifies input register.
291c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // Returns the condition on which a final split to
292c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // true and false label should be made, to optimize fallthrough.
293af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  Condition EmitTypeofIs(LTypeofIsAndBranch* instr, Register input);
294c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
295c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // Emits optimized code for %_IsObject(x).  Preserves input register.
296c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // Returns the condition on which a final split to
297c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // true and false label should be made, to optimize fallthrough.
298c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  Condition EmitIsObject(Register input,
299c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                         Label* is_not_object,
300c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                         Label* is_object);
301c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
3020ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  // Emits optimized code for %_IsString(x).  Preserves input register.
3030ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  // Returns the condition on which a final split to
3040ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  // true and false label should be made, to optimize fallthrough.
3050ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  Condition EmitIsString(Register input,
3060ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry                         Register temp1,
3071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                         Label* is_not_string,
3081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                         SmiCheck check_needed);
3090ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
310d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  // Emits optimized code for %_IsConstructCall().
311d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  // Caller should branch on equal condition.
312d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  void EmitIsConstructCall(Register temp);
313d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com
314160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  // Emits code for pushing either a tagged constant, a (non-double)
315160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  // register, or a stack slot operand.
316160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  void EmitPushTaggedOperand(LOperand* operand);
3173a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
3181b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  // Emits optimized code to deep-copy the contents of statically known
3191b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  // object graphs (e.g. object literal boilerplate).
3201b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  void EmitDeepCopy(Handle<JSObject> object,
3211b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                    Register result,
3221b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                    Register source,
32346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org                    int* offset,
32446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org                    AllocationSiteMode mode);
3251b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
326d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  void EnsureSpaceForLazyDeopt(int space_needed) V8_OVERRIDE;
327e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  void DoLoadKeyedExternalArray(LLoadKeyed* instr);
328e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr);
329e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  void DoLoadKeyedFixedArray(LLoadKeyed* instr);
330e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  void DoStoreKeyedExternalArray(LStoreKeyed* instr);
331e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr);
332e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  void DoStoreKeyedFixedArray(LStoreKeyed* instr);
333d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#ifdef _MSC_VER
334d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // On windows, you may not access the stack more than one page below
335d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // the most recently mapped page. To make the allocated area randomly
336d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // accessible, we write an arbitrary value to each page in range
337d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // rsp + offset - page_size .. rsp in turn.
338d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  void MakeSureStackPagesMapped(int offset);
339d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#endif
34027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org
341c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  ZoneList<LEnvironment*> deoptimizations_;
342aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org  ZoneList<Deoptimizer::JumpTableEntry> jump_table_;
343c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  ZoneList<Handle<Object> > deoptimization_literals_;
344c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  int inlined_function_count_;
345c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  Scope* const scope_;
346c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  TranslationBuffer translations_;
347c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  ZoneList<LDeferredCode*> deferred_;
348c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  int osr_pc_offset_;
349a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  bool frame_is_built_;
350c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
351c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // Builder that keeps track of safepoints in the code. The table
352c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // itself is emitted at the end of the generated code.
353c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  SafepointTableBuilder safepoints_;
354c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
355c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // Compiler from a set of parallel moves to a sequential list of moves.
356c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  LGapResolver resolver_;
357c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
35844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  Safepoint::Kind expected_safepoint_kind_;
35944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
36032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  class PushSafepointRegistersScope V8_FINAL BASE_EMBEDDED {
36144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org   public:
36244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    explicit PushSafepointRegistersScope(LCodeGen* codegen)
36344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org        : codegen_(codegen) {
364a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      ASSERT(codegen_->info()->is_calling());
36544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
36644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      codegen_->masm_->PushSafepointRegisters();
36744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      codegen_->expected_safepoint_kind_ = Safepoint::kWithRegisters;
36844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    }
36944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
37044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    ~PushSafepointRegistersScope() {
37144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kWithRegisters);
37244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      codegen_->masm_->PopSafepointRegisters();
37344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      codegen_->expected_safepoint_kind_ = Safepoint::kSimple;
37444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    }
37544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
37644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org   private:
37744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    LCodeGen* codegen_;
37844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  };
37944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
380c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  friend class LDeferredCode;
381c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  friend class LEnvironment;
382c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  friend class SafepointGenerator;
383c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  DISALLOW_COPY_AND_ASSIGN(LCodeGen);
384c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org};
385c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
386c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
387c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgclass LDeferredCode: public ZoneObject {
388c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org public:
389c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  explicit LDeferredCode(LCodeGen* codegen)
390c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      : codegen_(codegen),
391c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        external_exit_(NULL),
392c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        instruction_index_(codegen->current_instruction_) {
393c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    codegen->AddDeferredCode(this);
394c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  }
395c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
39632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  virtual ~LDeferredCode() {}
397c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  virtual void Generate() = 0;
398c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  virtual LInstruction* instr() = 0;
399c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
400f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  void SetExit(Label* exit) { external_exit_ = exit; }
401c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  Label* entry() { return &entry_; }
402c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
403c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  Label* done() { return codegen_->NeedsDeferredFrame() ? &done_ : exit(); }
404c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int instruction_index() const { return instruction_index_; }
405c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
406c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org protected:
407c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  LCodeGen* codegen() const { return codegen_; }
408c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  MacroAssembler* masm() const { return codegen_->masm(); }
409c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
410c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org private:
411c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  LCodeGen* codegen_;
412c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  Label entry_;
413c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  Label exit_;
414c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  Label done_;
415c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  Label* external_exit_;
416c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int instruction_index_;
417a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
418a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
419a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} }  // namespace v8::internal
420a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
421a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif  // V8_X64_LITHIUM_CODEGEN_X64_H_
422