1864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 2864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be 3864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// found in the LICENSE file. 4864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#ifndef V8_X87_LITHIUM_CODEGEN_X87_H_ 6864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#define V8_X87_LITHIUM_CODEGEN_X87_H_ 7864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org#include <map> 9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/x87/lithium-x87.h" 10864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 115de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/logging.h" 12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/deoptimizer.h" 13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/lithium-codegen.h" 14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/safepoint-table.h" 15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/scopes.h" 16196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/utils.h" 174b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/x87/lithium-gap-resolver-x87.h" 18864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 19864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace v8 { 20864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace internal { 21864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 22864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Forward declarations. 23864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgclass LDeferredCode; 24864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgclass LGapNode; 25864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgclass SafepointGenerator; 26864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 27864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgclass LCodeGen: public LCodeGenBase { 28864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 29864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info) 30864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : LCodeGenBase(chunk, assembler, info), 31864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org deoptimizations_(4, info->zone()), 32864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org jump_table_(4, info->zone()), 33864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org deoptimization_literals_(8, info->zone()), 34864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inlined_function_count_(0), 35864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org scope_(info->scope()), 36864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org translations_(info->zone()), 37864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org deferred_(8, info->zone()), 38864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org dynamic_frame_alignment_(false), 39864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org support_aligned_spilled_doubles_(false), 40864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org osr_pc_offset_(-1), 41864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org frame_is_built_(false), 42864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org x87_stack_(assembler), 43864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org safepoints_(info->zone()), 44864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org resolver_(this), 45864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org expected_safepoint_kind_(Safepoint::kSimple) { 46864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PopulateDeoptimizationLiteralsWithInlinedFunctions(); 47864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 48864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 49864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int LookupDestination(int block_id) const { 50864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return chunk()->LookupDestination(block_id); 51864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 52864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 53864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool IsNextEmittedBlock(int block_id) const { 54864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return LookupDestination(block_id) == GetNextEmittedBlock(); 55864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 56864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 57864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool NeedsEagerFrame() const { 58864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return GetStackSlotCount() > 0 || 59864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org info()->is_non_deferred_calling() || 60864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org !info()->IsStub() || 61864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org info()->requires_frame(); 62864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 63864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool NeedsDeferredFrame() const { 64864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return !NeedsEagerFrame() && info()->is_deferred_calling(); 65864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 66864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 67864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Support for converting LOperands to assembler types. 68864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand ToOperand(LOperand* op) const; 69864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register ToRegister(LOperand* op) const; 70864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Register ToX87Register(LOperand* op) const; 71864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 72864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool IsInteger32(LConstantOperand* op) const; 73864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool IsSmi(LConstantOperand* op) const; 74864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate ToImmediate(LOperand* op, const Representation& r) const { 75864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return Immediate(ToRepresentation(LConstantOperand::cast(op), r)); 76864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 77864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org double ToDouble(LConstantOperand* op) const; 78864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 79864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Support for non-sse2 (x87) floating point stack handling. 80864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // These functions maintain the mapping of physical stack registers to our 81864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // virtual registers between instructions. 82864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org enum X87OperandType { kX87DoubleOperand, kX87FloatOperand, kX87IntOperand }; 83864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 84864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void X87Mov(X87Register reg, Operand src, 85864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87OperandType operand = kX87DoubleOperand); 86864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void X87Mov(Operand src, X87Register reg, 87864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87OperandType operand = kX87DoubleOperand); 8806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void X87Mov(X87Register reg, X87Register src, 8906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87OperandType operand = kX87DoubleOperand); 90864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 91864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void X87PrepareBinaryOp( 92864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Register left, X87Register right, X87Register result); 93864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 94864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void X87LoadForUsage(X87Register reg); 95864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void X87LoadForUsage(X87Register reg1, X87Register reg2); 96864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void X87PrepareToWrite(X87Register reg) { x87_stack_.PrepareToWrite(reg); } 97864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void X87CommitWrite(X87Register reg) { x87_stack_.CommitWrite(reg); } 98864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 99864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void X87Fxch(X87Register reg, int other_slot = 0) { 100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org x87_stack_.Fxch(reg, other_slot); 101864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void X87Free(X87Register reg) { 103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org x87_stack_.Free(reg); 104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool X87StackEmpty() { 108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return x87_stack_.depth() == 0; 109864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 110864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 111864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Object> ToHandle(LConstantOperand* op) const; 112864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The operand denoting the second word (the one with a higher address) of 114864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // a double stack slot. 115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand HighOperand(LOperand* op); 116864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 117864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Try to generate code for the entire chunk, but it may fail if the 118864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // chunk contains constructs we cannot handle. Returns true if the 119864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // code generation attempt succeeded. 120864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool GenerateCode(); 121864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 122864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Finish the code by setting stack height, safepoint, and bailout 123864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // information on it. 124864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void FinishCode(Handle<Code> code); 125864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 126864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Deferred code support. 127864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void DoDeferredNumberTagD(LNumberTagD* instr); 128864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 129864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 }; 130864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void DoDeferredNumberTagIU(LInstruction* instr, 131864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* value, 132864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* temp, 133864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org IntegerSignedness signedness); 134864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 135864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void DoDeferredTaggedToI(LTaggedToI* instr, Label* done); 136864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr); 137864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void DoDeferredStackCheck(LStackCheck* instr); 138864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr); 139864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void DoDeferredStringCharFromCode(LStringCharFromCode* instr); 140864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void DoDeferredAllocate(LAllocate* instr); 141864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, 142864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* map_check); 143864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void DoDeferredInstanceMigration(LCheckMaps* instr, Register object); 144864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr, 145864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register object, 146864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register index); 147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 148864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Parallel move support. 149864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void DoParallelMove(LParallelMove* move); 150864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void DoGap(LGap* instr); 151864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 152864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Emit frame translation commands for an environment. 153864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void WriteTranslation(LEnvironment* environment, Translation* translation); 154864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 155864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void EnsureRelocSpaceForDeoptimization(); 156864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Declare methods that deal with the individual node types. 158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#define DECLARE_DO(type) void Do##type(L##type* node); 159864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO) 160864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#undef DECLARE_DO 161864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 163864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org StrictMode strict_mode() const { return info()->strict_mode(); } 164864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 165864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Scope* scope() const { return scope_; } 166864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 167864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void EmitClassOfTest(Label* if_true, 168864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_false, 169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<String> class_name, 170864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register input, 171864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temporary, 172864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temporary2); 173864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 174864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int GetStackSlotCount() const { return chunk()->spill_slot_count(); } 175864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 176864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); } 177864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 178864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Code generation passes. Returns true if code generation should 179864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // continue. 180ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org void GenerateBodyInstructionPre(LInstruction* instr) OVERRIDE; 181ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org void GenerateBodyInstructionPost(LInstruction* instr) OVERRIDE; 182864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool GeneratePrologue(); 183864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool GenerateDeferredCode(); 184864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool GenerateJumpTable(); 185864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool GenerateSafepointTable(); 186864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Generates the custom OSR entrypoint and sets the osr_pc_offset. 188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void GenerateOsrPrologue(); 189864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 190864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org enum SafepointMode { 191864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RECORD_SIMPLE_SAFEPOINT, 192864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS 193864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org }; 194864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 195864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CallCode(Handle<Code> code, 196864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RelocInfo::Mode mode, 197864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LInstruction* instr); 198864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 199864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CallCodeGeneric(Handle<Code> code, 200864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RelocInfo::Mode mode, 201864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LInstruction* instr, 202864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SafepointMode safepoint_mode); 203864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 20406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void CallRuntime(const Runtime::Function* fun, int argc, LInstruction* instr, 20506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org SaveFPRegsMode save_doubles = kDontSaveFPRegs); 206864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 207864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CallRuntime(Runtime::FunctionId id, 208864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int argc, 209864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LInstruction* instr) { 210864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const Runtime::Function* function = Runtime::FunctionForId(id); 211864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallRuntime(function, argc, instr); 212864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 213864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 214864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CallRuntimeFromDeferred(Runtime::FunctionId id, 215864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int argc, 216864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LInstruction* instr, 217864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* context); 218864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 219864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void LoadContextFromDeferred(LOperand* context); 220864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 221864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org enum EDIState { 222864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EDI_UNINITIALIZED, 223864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EDI_CONTAINS_TARGET 224864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org }; 225864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 226864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Generate a direct call to a known function. Expects the function 227864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // to be in edi. 228864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CallKnownFunction(Handle<JSFunction> function, 229864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int formal_parameter_count, 230864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int arity, 231864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LInstruction* instr, 232864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EDIState edi_state); 233864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 234864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void RecordSafepointWithLazyDeopt(LInstruction* instr, 235864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SafepointMode safepoint_mode); 236864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 237864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void RegisterEnvironmentForDeoptimization(LEnvironment* environment, 238864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Safepoint::DeoptMode mode); 23906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void DeoptimizeIf(Condition cc, LInstruction* instr, const char* detail, 240864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Deoptimizer::BailoutType bailout_type); 241b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org void DeoptimizeIf(Condition cc, LInstruction* instr, const char* detail); 242864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 243864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool DeoptEveryNTimes() { 244864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return FLAG_deopt_every_n_times != 0 && !info()->IsStub(); 245864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 246864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 247864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void AddToTranslation(LEnvironment* environment, 248864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Translation* translation, 249864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* op, 250864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool is_tagged, 251864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool is_uint32, 252864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int* object_index_pointer, 253864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int* dematerialized_index_pointer); 254864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void PopulateDeoptimizationData(Handle<Code> code); 255864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int DefineDeoptimizationLiteral(Handle<Object> literal); 256864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 257864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void PopulateDeoptimizationLiteralsWithInlinedFunctions(); 258864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 259864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register ToRegister(int index) const; 260864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Register ToX87Register(int index) const; 261864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t ToRepresentation(LConstantOperand* op, const Representation& r) const; 262864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t ToInteger32(LConstantOperand* op) const; 263864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference ToExternalReference(LConstantOperand* op) const; 264864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 265864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand BuildFastArrayOperand(LOperand* elements_pointer, 266864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* key, 267864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Representation key_representation, 268864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ElementsKind elements_kind, 269864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org uint32_t base_offset); 270864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 271864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand BuildSeqStringOperand(Register string, 272864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* index, 273864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org String::Encoding encoding); 274864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 275864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void EmitIntegerMathAbs(LMathAbs* instr); 276864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 277864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Support for recording safepoint and position information. 278864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void RecordSafepoint(LPointerMap* pointers, 279864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Safepoint::Kind kind, 280864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int arguments, 281864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Safepoint::DeoptMode mode); 282864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode); 283864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void RecordSafepoint(Safepoint::DeoptMode mode); 284864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void RecordSafepointWithRegisters(LPointerMap* pointers, 285864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int arguments, 286864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Safepoint::DeoptMode mode); 287864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 288ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org void RecordAndWritePosition(int position) OVERRIDE; 289864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 290864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static Condition TokenToCondition(Token::Value op, bool is_unsigned); 291864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void EmitGoto(int block); 292864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 293864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // EmitBranch expects to be the last instruction of a block. 294864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org template<class InstrType> 295864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void EmitBranch(InstrType instr, Condition cc); 296864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org template<class InstrType> 297864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void EmitFalseBranch(InstrType instr, Condition cc); 298a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org void EmitNumberUntagDNoSSE2(LNumberUntagD* instr, Register input, 299a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Register temp, X87Register res_reg, 300a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org NumberUntagDMode mode); 301864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 302864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Emits optimized code for typeof x == "y". Modifies input register. 303864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Returns the condition on which a final split to 304864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // true and false label should be made, to optimize fallthrough. 305864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Condition EmitTypeofIs(LTypeofIsAndBranch* instr, Register input); 306864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 307864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Emits optimized code for %_IsObject(x). Preserves input register. 308864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Returns the condition on which a final split to 309864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // true and false label should be made, to optimize fallthrough. 310864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Condition EmitIsObject(Register input, 311864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp1, 312864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* is_not_object, 313864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* is_object); 314864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 315864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Emits optimized code for %_IsString(x). Preserves input register. 316864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Returns the condition on which a final split to 317864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // true and false label should be made, to optimize fallthrough. 318864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Condition EmitIsString(Register input, 319864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp1, 320864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* is_not_string, 321864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SmiCheck check_needed); 322864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 323864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Emits optimized code for %_IsConstructCall(). 324864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Caller should branch on equal condition. 325864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void EmitIsConstructCall(Register temp); 326864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 327864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Emits optimized code to deep-copy the contents of statically known 328864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // object graphs (e.g. object literal boilerplate). 329864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void EmitDeepCopy(Handle<JSObject> object, 330864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result, 331864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register source, 332864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int* offset, 333864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AllocationSiteMode mode); 334864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 335ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org void EnsureSpaceForLazyDeopt(int space_needed) OVERRIDE; 336864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void DoLoadKeyedExternalArray(LLoadKeyed* instr); 337864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr); 338864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void DoLoadKeyedFixedArray(LLoadKeyed* instr); 339864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void DoStoreKeyedExternalArray(LStoreKeyed* instr); 340864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr); 341864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void DoStoreKeyedFixedArray(LStoreKeyed* instr); 342864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 343fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org template <class T> 344fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org void EmitVectorLoadICRegisters(T* instr); 345fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org 346864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void EmitReturn(LReturn* instr, bool dynamic_frame_alignment); 347864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 348864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Emits code for pushing either a tagged constant, a (non-double) 349864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // register, or a stack slot operand. 350864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void EmitPushTaggedOperand(LOperand* operand); 351864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 352864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void X87Fld(Operand src, X87OperandType opts); 353864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 354864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void EmitFlushX87ForDeopt(); 355864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void FlushX87StackIfNecessary(LInstruction* instr) { 356864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org x87_stack_.FlushIfNecessary(instr, this); 357864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 358864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org friend class LGapResolver; 359864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 360864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#ifdef _MSC_VER 361864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // On windows, you may not access the stack more than one page below 362864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the most recently mapped page. To make the allocated area randomly 363864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // accessible, we write an arbitrary value to each page in range 364864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // esp + offset - page_size .. esp in turn. 365864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void MakeSureStackPagesMapped(int offset); 366864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif 367864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 368864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<LEnvironment*> deoptimizations_; 369864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Deoptimizer::JumpTableEntry> jump_table_; 370864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Handle<Object> > deoptimization_literals_; 371864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int inlined_function_count_; 372864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Scope* const scope_; 373864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org TranslationBuffer translations_; 374864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<LDeferredCode*> deferred_; 375864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool dynamic_frame_alignment_; 376864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool support_aligned_spilled_doubles_; 377864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int osr_pc_offset_; 378864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool frame_is_built_; 379864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 38006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org class X87Stack : public ZoneObject { 381864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 382864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org explicit X87Stack(MacroAssembler* masm) 383864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : stack_depth_(0), is_mutable_(true), masm_(masm) { } 384864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org explicit X87Stack(const X87Stack& other) 385864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : stack_depth_(other.stack_depth_), is_mutable_(false), masm_(masm()) { 386864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < stack_depth_; i++) { 387864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org stack_[i] = other.stack_[i]; 388864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 389864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 390864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool operator==(const X87Stack& other) const { 391864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (stack_depth_ != other.stack_depth_) return false; 392864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < stack_depth_; i++) { 393864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!stack_[i].is(other.stack_[i])) return false; 394864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 395864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return true; 396864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 39706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Stack& operator=(const X87Stack& other) { 39806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org stack_depth_ = other.stack_depth_; 39906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org for (int i = 0; i < stack_depth_; i++) { 40006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org stack_[i] = other.stack_[i]; 40106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 40206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org return *this; 40306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 404864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool Contains(X87Register reg); 405864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Fxch(X87Register reg, int other_slot = 0); 406864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Free(X87Register reg); 407864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void PrepareToWrite(X87Register reg); 408864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CommitWrite(X87Register reg); 409864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void FlushIfNecessary(LInstruction* instr, LCodeGen* cgen); 41006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void LeavingBlock(int current_block_id, LGoto* goto_instr, LCodeGen* cgen); 411864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int depth() const { return stack_depth_; } 41206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org int GetLayout(); 41306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org int st(X87Register reg) { return st2idx(ArrayIndex(reg)); } 414864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void pop() { 415e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_mutable_); 416864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org stack_depth_--; 417864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 418864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void push(X87Register reg) { 419e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_mutable_); 420e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(stack_depth_ < X87Register::kMaxNumAllocatableRegisters); 421864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org stack_[stack_depth_] = reg; 422864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org stack_depth_++; 423864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 424864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 425864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org MacroAssembler* masm() const { return masm_; } 426864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Isolate* isolate() const { return masm_->isolate(); } 427864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 428864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 429864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int ArrayIndex(X87Register reg); 430864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int st2idx(int pos); 431864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 432864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Register stack_[X87Register::kMaxNumAllocatableRegisters]; 433864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int stack_depth_; 434864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool is_mutable_; 435864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org MacroAssembler* masm_; 436864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org }; 437864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Stack x87_stack_; 43806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // block_id -> X87Stack*; 43906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org typedef std::map<int, X87Stack*> X87StackMap; 44006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87StackMap x87_stack_map_; 441864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 442864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Builder that keeps track of safepoints in the code. The table 443864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // itself is emitted at the end of the generated code. 444864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SafepointTableBuilder safepoints_; 445864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 446864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Compiler from a set of parallel moves to a sequential list of moves. 447864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LGapResolver resolver_; 448864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 449864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Safepoint::Kind expected_safepoint_kind_; 450864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 451ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class PushSafepointRegistersScope FINAL BASE_EMBEDDED { 452864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 453864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org explicit PushSafepointRegistersScope(LCodeGen* codegen) 454864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : codegen_(codegen) { 455e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kSimple); 456864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen_->masm_->PushSafepointRegisters(); 457864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen_->expected_safepoint_kind_ = Safepoint::kWithRegisters; 458e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(codegen_->info()->is_calling()); 459864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 460864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 461864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ~PushSafepointRegistersScope() { 462e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kWithRegisters); 463864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen_->masm_->PopSafepointRegisters(); 464864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen_->expected_safepoint_kind_ = Safepoint::kSimple; 465864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 466864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 467864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 468864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LCodeGen* codegen_; 469864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org }; 470864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 471864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org friend class LDeferredCode; 472864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org friend class LEnvironment; 473864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org friend class SafepointGenerator; 47406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org friend class X87Stack; 475864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DISALLOW_COPY_AND_ASSIGN(LCodeGen); 476864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 477864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 478864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 479864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgclass LDeferredCode : public ZoneObject { 480864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 481864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org explicit LDeferredCode(LCodeGen* codegen, const LCodeGen::X87Stack& x87_stack) 482864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : codegen_(codegen), 483864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org external_exit_(NULL), 484864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instruction_index_(codegen->current_instruction_), 485864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org x87_stack_(x87_stack) { 486864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen->AddDeferredCode(this); 487864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 488864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 489864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org virtual ~LDeferredCode() {} 490864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org virtual void Generate() = 0; 491864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org virtual LInstruction* instr() = 0; 492864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 493864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void SetExit(Label* exit) { external_exit_ = exit; } 494864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* entry() { return &entry_; } 495864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; } 496864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* done() { return codegen_->NeedsDeferredFrame() ? &done_ : exit(); } 497864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int instruction_index() const { return instruction_index_; } 498864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const LCodeGen::X87Stack& x87_stack() const { return x87_stack_; } 499864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 500864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org protected: 501864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LCodeGen* codegen() const { return codegen_; } 502864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org MacroAssembler* masm() const { return codegen_->masm(); } 503864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 504864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 505864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LCodeGen* codegen_; 506864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label entry_; 507864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label exit_; 508864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* external_exit_; 509864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done_; 510864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int instruction_index_; 511864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LCodeGen::X87Stack x87_stack_; 512864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 513864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 514864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} } // namespace v8::internal 515864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 516864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif // V8_X87_LITHIUM_CODEGEN_X87_H_ 517