10b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey// Copyright 2012 the V8 project authors. All rights reserved. 20b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey// Use of this source code is governed by a BSD-style license that can be 30b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey// found in the LICENSE file. 40b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 50b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey#ifndef V8_IA32_LITHIUM_CODEGEN_IA32_H_ 60b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey#define V8_IA32_LITHIUM_CODEGEN_IA32_H_ 70b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 80b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey#include "src/ia32/lithium-ia32.h" 90b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 100b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey#include "src/base/logging.h" 110b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey#include "src/deoptimizer.h" 120b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey#include "src/ia32/lithium-gap-resolver-ia32.h" 130b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey#include "src/lithium-codegen.h" 140b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey#include "src/safepoint-table.h" 150b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey#include "src/scopes.h" 160b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey#include "src/utils.h" 170b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 180b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkeynamespace v8 { 190b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkeynamespace internal { 200b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 210b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey// Forward declarations. 220b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkeyclass LDeferredCode; 230b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkeyclass LGapNode; 240b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkeyclass SafepointGenerator; 25c29dd61cbfc9f073239bdce3f4fe397deae2c623Jeff Sharkey 260b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkeyclass LCodeGen: public LCodeGenBase { 270b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey public: 280b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info) 290b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey : LCodeGenBase(chunk, assembler, info), 300b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey deoptimizations_(4, info->zone()), 310b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey jump_table_(4, info->zone()), 320b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey deoptimization_literals_(8, info->zone()), 330b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey inlined_function_count_(0), 340b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey scope_(info->scope()), 350b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey translations_(info->zone()), 360b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey deferred_(8, info->zone()), 370b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey dynamic_frame_alignment_(false), 380b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey support_aligned_spilled_doubles_(false), 390b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey osr_pc_offset_(-1), 400b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey frame_is_built_(false), 410b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey safepoints_(info->zone()), 420b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey resolver_(this), 430b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey expected_safepoint_kind_(Safepoint::kSimple) { 440b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey PopulateDeoptimizationLiteralsWithInlinedFunctions(); 450b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey } 460b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 470b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey int LookupDestination(int block_id) const { 480b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey return chunk()->LookupDestination(block_id); 49c29dd61cbfc9f073239bdce3f4fe397deae2c623Jeff Sharkey } 500b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 510b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey bool IsNextEmittedBlock(int block_id) const { 520b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey return LookupDestination(block_id) == GetNextEmittedBlock(); 530b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey } 540b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 550b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey bool NeedsEagerFrame() const { 560b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey return GetStackSlotCount() > 0 || 570b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey info()->is_non_deferred_calling() || 580b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey !info()->IsStub() || 590b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey info()->requires_frame(); 600b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey } 610b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey bool NeedsDeferredFrame() const { 620b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey return !NeedsEagerFrame() && info()->is_deferred_calling(); 630b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey } 640b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 650b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey // Support for converting LOperands to assembler types. 660b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey Operand ToOperand(LOperand* op) const; 670b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey Register ToRegister(LOperand* op) const; 680b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey XMMRegister ToDoubleRegister(LOperand* op) const; 690b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 700b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey bool IsInteger32(LConstantOperand* op) const; 710b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey bool IsSmi(LConstantOperand* op) const; 720b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey Immediate ToImmediate(LOperand* op, const Representation& r) const { 730b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey return Immediate(ToRepresentation(LConstantOperand::cast(op), r)); 740b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey } 750b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey double ToDouble(LConstantOperand* op) const; 760b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 770b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey Handle<Object> ToHandle(LConstantOperand* op) const; 780b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 790b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey // The operand denoting the second word (the one with a higher address) of 800b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey // a double stack slot. 810b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey Operand HighOperand(LOperand* op); 820b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 830b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey // Try to generate code for the entire chunk, but it may fail if the 840b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey // chunk contains constructs we cannot handle. Returns true if the 850b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey // code generation attempt succeeded. 860b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey bool GenerateCode(); 870b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 880b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey // Finish the code by setting stack height, safepoint, and bailout 890b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey // information on it. 900b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void FinishCode(Handle<Code> code); 910b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 920b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey // Deferred code support. 930b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void DoDeferredNumberTagD(LNumberTagD* instr); 940b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 950b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 }; 960b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void DoDeferredNumberTagIU(LInstruction* instr, 970b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey LOperand* value, 980b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey LOperand* temp, 990b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey IntegerSignedness signedness); 1000b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 1010b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void DoDeferredTaggedToI(LTaggedToI* instr, Label* done); 1020b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr); 1030b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void DoDeferredStackCheck(LStackCheck* instr); 1040b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr); 1050b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void DoDeferredStringCharFromCode(LStringCharFromCode* instr); 1060b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void DoDeferredAllocate(LAllocate* instr); 1070b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, 1080b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey Label* map_check); 1090b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void DoDeferredInstanceMigration(LCheckMaps* instr, Register object); 1100b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr, 1110b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey Register object, 1120b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey Register index); 1130b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 1140b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey // Parallel move support. 1150b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void DoParallelMove(LParallelMove* move); 1160b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void DoGap(LGap* instr); 1170b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 1180b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey // Emit frame translation commands for an environment. 1190b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void WriteTranslation(LEnvironment* environment, Translation* translation); 1200b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 1210b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void EnsureRelocSpaceForDeoptimization(); 1220b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 1230b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey // Declare methods that deal with the individual node types. 1240b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey#define DECLARE_DO(type) void Do##type(L##type* node); 1250b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO) 1260b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey#undef DECLARE_DO 1270b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 1280b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey private: 1290b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey StrictMode strict_mode() const { return info()->strict_mode(); } 1300b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 1310b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey Scope* scope() const { return scope_; } 1320b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 1330b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey XMMRegister double_scratch0() const { return xmm0; } 1340b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 1350b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void EmitClassOfTest(Label* if_true, 136c29dd61cbfc9f073239bdce3f4fe397deae2c623Jeff Sharkey Label* if_false, 1370b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey Handle<String> class_name, 1380b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey Register input, 1390b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey Register temporary, 1400b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey Register temporary2); 1410b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 1420b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey int GetStackSlotCount() const { return chunk()->spill_slot_count(); } 1430b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 1440b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); } 1450b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 1460b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void SaveCallerDoubles(); 1470b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void RestoreCallerDoubles(); 1480b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 1490b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey // Code generation passes. Returns true if code generation should 1500b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey // continue. 1510b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void GenerateBodyInstructionPre(LInstruction* instr) OVERRIDE; 1520b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void GenerateBodyInstructionPost(LInstruction* instr) OVERRIDE; 1530b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey bool GeneratePrologue(); 1540b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey bool GenerateDeferredCode(); 1550b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey bool GenerateJumpTable(); 1560b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey bool GenerateSafepointTable(); 1570b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 1580b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey // Generates the custom OSR entrypoint and sets the osr_pc_offset. 1590b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void GenerateOsrPrologue(); 1600b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 1610b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey enum SafepointMode { 1620b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey RECORD_SIMPLE_SAFEPOINT, 1630b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS 1640b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey }; 1650b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 1660b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void CallCode(Handle<Code> code, 1670b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey RelocInfo::Mode mode, 1680b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey LInstruction* instr); 1690b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 1700b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void CallCodeGeneric(Handle<Code> code, 1710b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey RelocInfo::Mode mode, 1720b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey LInstruction* instr, 1730b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey SafepointMode safepoint_mode); 1740b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 1750b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void CallRuntime(const Runtime::Function* fun, 1760b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey int argc, 1770b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey LInstruction* instr, 1780b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey SaveFPRegsMode save_doubles = kDontSaveFPRegs); 1790b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 180c29dd61cbfc9f073239bdce3f4fe397deae2c623Jeff Sharkey void CallRuntime(Runtime::FunctionId id, 1810b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey int argc, 1820b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey LInstruction* instr) { 183770a53288643197a903999fac5469e4f1e6e4b2cJeff Sharkey const Runtime::Function* function = Runtime::FunctionForId(id); 184770a53288643197a903999fac5469e4f1e6e4b2cJeff Sharkey CallRuntime(function, argc, instr); 185770a53288643197a903999fac5469e4f1e6e4b2cJeff Sharkey } 186770a53288643197a903999fac5469e4f1e6e4b2cJeff Sharkey 187770a53288643197a903999fac5469e4f1e6e4b2cJeff Sharkey void CallRuntimeFromDeferred(Runtime::FunctionId id, 188770a53288643197a903999fac5469e4f1e6e4b2cJeff Sharkey int argc, 189770a53288643197a903999fac5469e4f1e6e4b2cJeff Sharkey LInstruction* instr, 190770a53288643197a903999fac5469e4f1e6e4b2cJeff Sharkey LOperand* context); 191770a53288643197a903999fac5469e4f1e6e4b2cJeff Sharkey 192770a53288643197a903999fac5469e4f1e6e4b2cJeff Sharkey void LoadContextFromDeferred(LOperand* context); 193770a53288643197a903999fac5469e4f1e6e4b2cJeff Sharkey 194770a53288643197a903999fac5469e4f1e6e4b2cJeff Sharkey enum EDIState { 195770a53288643197a903999fac5469e4f1e6e4b2cJeff Sharkey EDI_UNINITIALIZED, 196770a53288643197a903999fac5469e4f1e6e4b2cJeff Sharkey EDI_CONTAINS_TARGET 197770a53288643197a903999fac5469e4f1e6e4b2cJeff Sharkey }; 198770a53288643197a903999fac5469e4f1e6e4b2cJeff Sharkey 199770a53288643197a903999fac5469e4f1e6e4b2cJeff Sharkey // Generate a direct call to a known function. Expects the function 200770a53288643197a903999fac5469e4f1e6e4b2cJeff Sharkey // to be in edi. 201770a53288643197a903999fac5469e4f1e6e4b2cJeff Sharkey void CallKnownFunction(Handle<JSFunction> function, 2020b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey int formal_parameter_count, 2030b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey int arity, 2040b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey LInstruction* instr, 2050b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey EDIState edi_state); 2060b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 2070b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void RecordSafepointWithLazyDeopt(LInstruction* instr, 2080b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey SafepointMode safepoint_mode); 2090b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 2100b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void RegisterEnvironmentForDeoptimization(LEnvironment* environment, 2110b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey Safepoint::DeoptMode mode); 2120b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void DeoptimizeIf(Condition cc, LInstruction* instr, const char* detail, 21303d30a573b8bc8e169e153a0fffa053ffedcd5eeAlan Viverette Deoptimizer::BailoutType bailout_type); 2140b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void DeoptimizeIf(Condition cc, LInstruction* instr, const char* detail); 2150b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 2160b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey bool DeoptEveryNTimes() { 2170b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey return FLAG_deopt_every_n_times != 0 && !info()->IsStub(); 2180b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey } 219563ee0fbe99c234f3364044cb762a75abbbaa797Jeff Sharkey 220563ee0fbe99c234f3364044cb762a75abbbaa797Jeff Sharkey void AddToTranslation(LEnvironment* environment, 221563ee0fbe99c234f3364044cb762a75abbbaa797Jeff Sharkey Translation* translation, 222563ee0fbe99c234f3364044cb762a75abbbaa797Jeff Sharkey LOperand* op, 223563ee0fbe99c234f3364044cb762a75abbbaa797Jeff Sharkey bool is_tagged, 224563ee0fbe99c234f3364044cb762a75abbbaa797Jeff Sharkey bool is_uint32, 22503d30a573b8bc8e169e153a0fffa053ffedcd5eeAlan Viverette int* object_index_pointer, 226563ee0fbe99c234f3364044cb762a75abbbaa797Jeff Sharkey int* dematerialized_index_pointer); 227563ee0fbe99c234f3364044cb762a75abbbaa797Jeff Sharkey void PopulateDeoptimizationData(Handle<Code> code); 228563ee0fbe99c234f3364044cb762a75abbbaa797Jeff Sharkey int DefineDeoptimizationLiteral(Handle<Object> literal); 22903d30a573b8bc8e169e153a0fffa053ffedcd5eeAlan Viverette 230563ee0fbe99c234f3364044cb762a75abbbaa797Jeff Sharkey void PopulateDeoptimizationLiteralsWithInlinedFunctions(); 23103d30a573b8bc8e169e153a0fffa053ffedcd5eeAlan Viverette 232563ee0fbe99c234f3364044cb762a75abbbaa797Jeff Sharkey Register ToRegister(int index) const; 233563ee0fbe99c234f3364044cb762a75abbbaa797Jeff Sharkey XMMRegister ToDoubleRegister(int index) const; 234563ee0fbe99c234f3364044cb762a75abbbaa797Jeff Sharkey int32_t ToRepresentation(LConstantOperand* op, const Representation& r) const; 235563ee0fbe99c234f3364044cb762a75abbbaa797Jeff Sharkey int32_t ToInteger32(LConstantOperand* op) const; 236563ee0fbe99c234f3364044cb762a75abbbaa797Jeff Sharkey ExternalReference ToExternalReference(LConstantOperand* op) const; 237563ee0fbe99c234f3364044cb762a75abbbaa797Jeff Sharkey 2380b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey Operand BuildFastArrayOperand(LOperand* elements_pointer, 2390b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey LOperand* key, 24003d30a573b8bc8e169e153a0fffa053ffedcd5eeAlan Viverette Representation key_representation, 2410b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey ElementsKind elements_kind, 2420b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey uint32_t base_offset); 2430b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 2440b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey Operand BuildSeqStringOperand(Register string, 2450b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey LOperand* index, 24603d30a573b8bc8e169e153a0fffa053ffedcd5eeAlan Viverette String::Encoding encoding); 2470b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 2480b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void EmitIntegerMathAbs(LMathAbs* instr); 2490b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 2500b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey // Support for recording safepoint and position information. 2510b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void RecordSafepoint(LPointerMap* pointers, 2520b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey Safepoint::Kind kind, 2530b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey int arguments, 2540b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey Safepoint::DeoptMode mode); 2550b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode); 2560b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void RecordSafepoint(Safepoint::DeoptMode mode); 25703d30a573b8bc8e169e153a0fffa053ffedcd5eeAlan Viverette void RecordSafepointWithRegisters(LPointerMap* pointers, 2580b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey int arguments, 25903d30a573b8bc8e169e153a0fffa053ffedcd5eeAlan Viverette Safepoint::DeoptMode mode); 2600b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 26103d30a573b8bc8e169e153a0fffa053ffedcd5eeAlan Viverette void RecordAndWritePosition(int position) OVERRIDE; 2620b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey 26303d30a573b8bc8e169e153a0fffa053ffedcd5eeAlan Viverette static Condition TokenToCondition(Token::Value op, bool is_unsigned); 2640b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey void EmitGoto(int block); 26503d30a573b8bc8e169e153a0fffa053ffedcd5eeAlan Viverette 2660b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey // EmitBranch expects to be the last instruction of a block. 2670b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey template<class InstrType> 268c29dd61cbfc9f073239bdce3f4fe397deae2c623Jeff Sharkey void EmitBranch(InstrType instr, Condition cc); 269cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey template<class InstrType> 27003d30a573b8bc8e169e153a0fffa053ffedcd5eeAlan Viverette void EmitFalseBranch(InstrType instr, Condition cc); 271c29dd61cbfc9f073239bdce3f4fe397deae2c623Jeff Sharkey void EmitNumberUntagD(LNumberUntagD* instr, Register input, Register temp, 272cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey XMMRegister result, NumberUntagDMode mode); 273c29dd61cbfc9f073239bdce3f4fe397deae2c623Jeff Sharkey 274c29dd61cbfc9f073239bdce3f4fe397deae2c623Jeff Sharkey // Emits optimized code for typeof x == "y". Modifies input register. 275cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey // Returns the condition on which a final split to 276cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey // true and false label should be made, to optimize fallthrough. 277cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey Condition EmitTypeofIs(LTypeofIsAndBranch* instr, Register input); 278cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey 279cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey // Emits optimized code for %_IsObject(x). Preserves input register. 280cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey // Returns the condition on which a final split to 2810b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey // true and false label should be made, to optimize fallthrough. 282 Condition EmitIsObject(Register input, 283 Register temp1, 284 Label* is_not_object, 285 Label* is_object); 286 287 // Emits optimized code for %_IsString(x). Preserves input register. 288 // Returns the condition on which a final split to 289 // true and false label should be made, to optimize fallthrough. 290 Condition EmitIsString(Register input, 291 Register temp1, 292 Label* is_not_string, 293 SmiCheck check_needed); 294 295 // Emits optimized code for %_IsConstructCall(). 296 // Caller should branch on equal condition. 297 void EmitIsConstructCall(Register temp); 298 299 // Emits optimized code to deep-copy the contents of statically known 300 // object graphs (e.g. object literal boilerplate). 301 void EmitDeepCopy(Handle<JSObject> object, 302 Register result, 303 Register source, 304 int* offset, 305 AllocationSiteMode mode); 306 307 void EnsureSpaceForLazyDeopt(int space_needed) OVERRIDE; 308 void DoLoadKeyedExternalArray(LLoadKeyed* instr); 309 void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr); 310 void DoLoadKeyedFixedArray(LLoadKeyed* instr); 311 void DoStoreKeyedExternalArray(LStoreKeyed* instr); 312 void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr); 313 void DoStoreKeyedFixedArray(LStoreKeyed* instr); 314 315 template <class T> 316 void EmitVectorLoadICRegisters(T* instr); 317 318 void EmitReturn(LReturn* instr, bool dynamic_frame_alignment); 319 320 // Emits code for pushing either a tagged constant, a (non-double) 321 // register, or a stack slot operand. 322 void EmitPushTaggedOperand(LOperand* operand); 323 324 friend class LGapResolver; 325 326#ifdef _MSC_VER 327 // On windows, you may not access the stack more than one page below 328 // the most recently mapped page. To make the allocated area randomly 329 // accessible, we write an arbitrary value to each page in range 330 // esp + offset - page_size .. esp in turn. 331 void MakeSureStackPagesMapped(int offset); 332#endif 333 334 ZoneList<LEnvironment*> deoptimizations_; 335 ZoneList<Deoptimizer::JumpTableEntry> jump_table_; 336 ZoneList<Handle<Object> > deoptimization_literals_; 337 int inlined_function_count_; 338 Scope* const scope_; 339 TranslationBuffer translations_; 340 ZoneList<LDeferredCode*> deferred_; 341 bool dynamic_frame_alignment_; 342 bool support_aligned_spilled_doubles_; 343 int osr_pc_offset_; 344 bool frame_is_built_; 345 346 // Builder that keeps track of safepoints in the code. The table 347 // itself is emitted at the end of the generated code. 348 SafepointTableBuilder safepoints_; 349 350 // Compiler from a set of parallel moves to a sequential list of moves. 351 LGapResolver resolver_; 352 353 Safepoint::Kind expected_safepoint_kind_; 354 355 class PushSafepointRegistersScope FINAL BASE_EMBEDDED { 356 public: 357 explicit PushSafepointRegistersScope(LCodeGen* codegen) 358 : codegen_(codegen) { 359 DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kSimple); 360 codegen_->masm_->PushSafepointRegisters(); 361 codegen_->expected_safepoint_kind_ = Safepoint::kWithRegisters; 362 DCHECK(codegen_->info()->is_calling()); 363 } 364 365 ~PushSafepointRegistersScope() { 366 DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kWithRegisters); 367 codegen_->masm_->PopSafepointRegisters(); 368 codegen_->expected_safepoint_kind_ = Safepoint::kSimple; 369 } 370 371 private: 372 LCodeGen* codegen_; 373 }; 374 375 friend class LDeferredCode; 376 friend class LEnvironment; 377 friend class SafepointGenerator; 378 DISALLOW_COPY_AND_ASSIGN(LCodeGen); 379}; 380 381 382class LDeferredCode : public ZoneObject { 383 public: 384 explicit LDeferredCode(LCodeGen* codegen) 385 : codegen_(codegen), 386 external_exit_(NULL), 387 instruction_index_(codegen->current_instruction_) { 388 codegen->AddDeferredCode(this); 389 } 390 391 virtual ~LDeferredCode() {} 392 virtual void Generate() = 0; 393 virtual LInstruction* instr() = 0; 394 395 void SetExit(Label* exit) { external_exit_ = exit; } 396 Label* entry() { return &entry_; } 397 Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; } 398 Label* done() { return codegen_->NeedsDeferredFrame() ? &done_ : exit(); } 399 int instruction_index() const { return instruction_index_; } 400 401 protected: 402 LCodeGen* codegen() const { return codegen_; } 403 MacroAssembler* masm() const { return codegen_->masm(); } 404 405 private: 406 LCodeGen* codegen_; 407 Label entry_; 408 Label exit_; 409 Label* external_exit_; 410 Label done_; 411 int instruction_index_; 412}; 413 414} } // namespace v8::internal 415 416#endif // V8_IA32_LITHIUM_CODEGEN_IA32_H_ 417