| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #ifndef V8_A64_LITHIUM_CODEGEN_A64_H_ | 28 #ifndef V8_A64_LITHIUM_CODEGEN_A64_H_ |
| 29 #define V8_A64_LITHIUM_CODEGEN_A64_H_ | 29 #define V8_A64_LITHIUM_CODEGEN_A64_H_ |
| 30 | 30 |
| 31 #include "a64/lithium-a64.h" | 31 #include "a64/lithium-a64.h" |
| 32 | 32 |
| 33 #include "a64/lithium-gap-resolver-a64.h" | 33 #include "a64/lithium-gap-resolver-a64.h" |
| 34 #include "deoptimizer.h" | 34 #include "deoptimizer.h" |
| 35 #include "lithium-codegen.h" |
| 35 #include "safepoint-table.h" | 36 #include "safepoint-table.h" |
| 36 #include "scopes.h" | 37 #include "scopes.h" |
| 37 #include "v8utils.h" | 38 #include "v8utils.h" |
| 38 | 39 |
| 39 namespace v8 { | 40 namespace v8 { |
| 40 namespace internal { | 41 namespace internal { |
| 41 | 42 |
| 42 // Forward declarations. | 43 // Forward declarations. |
| 43 class LDeferredCode; | 44 class LDeferredCode; |
| 44 class SafepointGenerator; | 45 class SafepointGenerator; |
| 45 class BranchGenerator; | 46 class BranchGenerator; |
| 46 | 47 |
| 47 class LCodeGen BASE_EMBEDDED { | 48 class LCodeGen: public LCodeGenBase { |
| 48 public: | 49 public: |
| 49 LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info) | 50 LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info) |
| 50 : zone_(info->zone()), | 51 : LCodeGenBase(chunk, assembler, info), |
| 51 chunk_(static_cast<LPlatformChunk*>(chunk)), | |
| 52 masm_(assembler), | |
| 53 info_(info), | |
| 54 current_block_(-1), | |
| 55 current_instruction_(-1), | |
| 56 instructions_(chunk->instructions()), | |
| 57 deoptimizations_(4, info->zone()), | 52 deoptimizations_(4, info->zone()), |
| 58 deopt_jump_table_(4, info->zone()), | 53 deopt_jump_table_(4, info->zone()), |
| 59 deoptimization_literals_(8, info->zone()), | 54 deoptimization_literals_(8, info->zone()), |
| 60 inlined_function_count_(0), | 55 inlined_function_count_(0), |
| 61 scope_(info->scope()), | 56 scope_(info->scope()), |
| 62 status_(UNUSED), | |
| 63 translations_(info->zone()), | 57 translations_(info->zone()), |
| 64 deferred_(8, info->zone()), | 58 deferred_(8, info->zone()), |
| 65 osr_pc_offset_(-1), | 59 osr_pc_offset_(-1), |
| 66 last_lazy_deopt_pc_(0), | |
| 67 frame_is_built_(false), | 60 frame_is_built_(false), |
| 68 safepoints_(info->zone()), | 61 safepoints_(info->zone()), |
| 69 resolver_(this), | 62 resolver_(this), |
| 70 expected_safepoint_kind_(Safepoint::kSimple), | 63 expected_safepoint_kind_(Safepoint::kSimple), |
| 71 old_position_(RelocInfo::kNoPosition) { | 64 old_position_(RelocInfo::kNoPosition) { |
| 72 PopulateDeoptimizationLiteralsWithInlinedFunctions(); | 65 PopulateDeoptimizationLiteralsWithInlinedFunctions(); |
| 73 } | 66 } |
| 74 | 67 |
| 75 // Simple accessors. | 68 // Simple accessors. |
| 76 MacroAssembler* masm() const { return masm_; } | |
| 77 CompilationInfo* info() const { return info_; } | |
| 78 Zone* zone() const { return zone_; } | |
| 79 HGraph* graph() const { return chunk()->graph(); } | |
| 80 LPlatformChunk* chunk() const { return chunk_; } | |
| 81 Isolate* isolate() const { return info_->isolate(); } | |
| 82 Factory* factory() const { return isolate()->factory(); } | |
| 83 Scope* scope() const { return scope_; } | 69 Scope* scope() const { return scope_; } |
| 84 Heap* heap() const { return isolate()->heap(); } | |
| 85 | 70 |
| 86 int LookupDestination(int block_id) const { | 71 int LookupDestination(int block_id) const { |
| 87 return chunk()->LookupDestination(block_id); | 72 return chunk()->LookupDestination(block_id); |
| 88 } | 73 } |
| 89 | 74 |
| 90 bool IsNextEmittedBlock(int block_id) const { | 75 bool IsNextEmittedBlock(int block_id) const { |
| 91 return LookupDestination(block_id) == GetNextEmittedBlock(); | 76 return LookupDestination(block_id) == GetNextEmittedBlock(); |
| 92 } | 77 } |
| 93 | 78 |
| 94 bool NeedsEagerFrame() const { | 79 bool NeedsEagerFrame() const { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 Smi* ToSmi(LConstantOperand* op) const; | 118 Smi* ToSmi(LConstantOperand* op) const; |
| 134 double ToDouble(LConstantOperand* op) const; | 119 double ToDouble(LConstantOperand* op) const; |
| 135 DoubleRegister ToDoubleRegister(LOperand* op) const; | 120 DoubleRegister ToDoubleRegister(LOperand* op) const; |
| 136 | 121 |
| 137 // Declare methods that deal with the individual node types. | 122 // Declare methods that deal with the individual node types. |
| 138 #define DECLARE_DO(type) void Do##type(L##type* node); | 123 #define DECLARE_DO(type) void Do##type(L##type* node); |
| 139 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO) | 124 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO) |
| 140 #undef DECLARE_DO | 125 #undef DECLARE_DO |
| 141 | 126 |
| 142 private: | 127 private: |
| 143 enum Status { | |
| 144 UNUSED, | |
| 145 GENERATING, | |
| 146 DONE, | |
| 147 ABORTED | |
| 148 }; | |
| 149 | |
| 150 bool is_unused() const { return status_ == UNUSED; } | |
| 151 bool is_generating() const { return status_ == GENERATING; } | |
| 152 bool is_done() const { return status_ == DONE; } | |
| 153 bool is_aborted() const { return status_ == ABORTED; } | |
| 154 | |
| 155 // Return a double scratch register which can be used locally | 128 // Return a double scratch register which can be used locally |
| 156 // when generating code for a lithium instruction. | 129 // when generating code for a lithium instruction. |
| 157 DoubleRegister double_scratch() { return crankshaft_fp_scratch; } | 130 DoubleRegister double_scratch() { return crankshaft_fp_scratch; } |
| 158 | 131 |
| 159 // Deferred code support. | 132 // Deferred code support. |
| 160 void DoDeferredNumberTagD(LNumberTagD* instr); | 133 void DoDeferredNumberTagD(LNumberTagD* instr); |
| 161 void DoDeferredStackCheck(LStackCheck* instr); | 134 void DoDeferredStackCheck(LStackCheck* instr); |
| 162 void DoDeferredRandom(LRandom* instr); | 135 void DoDeferredRandom(LRandom* instr); |
| 163 void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr); | 136 void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr); |
| 164 void DoDeferredStringCharFromCode(LStringCharFromCode* instr); | 137 void DoDeferredStringCharFromCode(LStringCharFromCode* instr); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 176 LOperand* temp1, | 149 LOperand* temp1, |
| 177 LOperand* temp2); | 150 LOperand* temp2); |
| 178 void DoDeferredAllocate(LAllocate* instr); | 151 void DoDeferredAllocate(LAllocate* instr); |
| 179 void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr); | 152 void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr); |
| 180 void DoDeferredInstanceMigration(LCheckMaps* instr, Register object); | 153 void DoDeferredInstanceMigration(LCheckMaps* instr, Register object); |
| 181 | 154 |
| 182 Operand ToOperand32(LOperand* op, IntegerSignedness signedness); | 155 Operand ToOperand32(LOperand* op, IntegerSignedness signedness); |
| 183 | 156 |
| 184 static Condition TokenToCondition(Token::Value op, bool is_unsigned); | 157 static Condition TokenToCondition(Token::Value op, bool is_unsigned); |
| 185 void EmitGoto(int block); | 158 void EmitGoto(int block); |
| 186 int GetNextEmittedBlock() const; | |
| 187 void DoGap(LGap* instr); | 159 void DoGap(LGap* instr); |
| 188 | 160 |
| 189 // Generic version of EmitBranch. It contains some code to avoid emitting a | 161 // Generic version of EmitBranch. It contains some code to avoid emitting a |
| 190 // branch on the next emitted basic block where we could just fall-through. | 162 // branch on the next emitted basic block where we could just fall-through. |
| 191 // You shouldn't use that directly but rather consider one of the helper like | 163 // You shouldn't use that directly but rather consider one of the helper like |
| 192 // LCodeGen::EmitBranch, LCodeGen::EmitCompareAndBranch... | 164 // LCodeGen::EmitBranch, LCodeGen::EmitCompareAndBranch... |
| 193 template<class InstrType> | 165 template<class InstrType> |
| 194 void EmitBranchGeneric(InstrType instr, | 166 void EmitBranchGeneric(InstrType instr, |
| 195 const BranchGenerator& branch); | 167 const BranchGenerator& branch); |
| 196 | 168 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 Register key, | 246 Register key, |
| 275 bool key_is_tagged, | 247 bool key_is_tagged, |
| 276 ElementsKind elements_kind); | 248 ElementsKind elements_kind); |
| 277 | 249 |
| 278 void RegisterEnvironmentForDeoptimization(LEnvironment* environment, | 250 void RegisterEnvironmentForDeoptimization(LEnvironment* environment, |
| 279 Safepoint::DeoptMode mode); | 251 Safepoint::DeoptMode mode); |
| 280 | 252 |
| 281 int GetStackSlotCount() const { return chunk()->spill_slot_count(); } | 253 int GetStackSlotCount() const { return chunk()->spill_slot_count(); } |
| 282 | 254 |
| 283 void Abort(BailoutReason reason); | 255 void Abort(BailoutReason reason); |
| 284 void FPRINTF_CHECKING Comment(const char* format, ...); | |
| 285 | 256 |
| 286 void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); } | 257 void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); } |
| 287 | 258 |
| 288 // Emit frame translation commands for an environment. | 259 // Emit frame translation commands for an environment. |
| 289 void WriteTranslation(LEnvironment* environment, Translation* translation); | 260 void WriteTranslation(LEnvironment* environment, Translation* translation); |
| 290 | 261 |
| 291 void AddToTranslation(LEnvironment* environment, | 262 void AddToTranslation(LEnvironment* environment, |
| 292 Translation* translation, | 263 Translation* translation, |
| 293 LOperand* op, | 264 LOperand* op, |
| 294 bool is_tagged, | 265 bool is_tagged, |
| 295 bool is_uint32, | 266 bool is_uint32, |
| 296 int* object_index_pointer, | 267 int* object_index_pointer, |
| 297 int* dematerialized_index_pointer); | 268 int* dematerialized_index_pointer); |
| 298 | 269 |
| 299 // Code generation steps. Returns true if code generation should continue. | 270 // Code generation steps. Returns true if code generation should continue. |
| 300 bool GeneratePrologue(); | 271 bool GeneratePrologue(); |
| 301 bool GenerateBody(); | |
| 302 bool GenerateDeferredCode(); | 272 bool GenerateDeferredCode(); |
| 303 bool GenerateDeoptJumpTable(); | 273 bool GenerateDeoptJumpTable(); |
| 304 bool GenerateSafepointTable(); | 274 bool GenerateSafepointTable(); |
| 305 | 275 |
| 306 // Generates the custom OSR entrypoint and sets the osr_pc_offset. | 276 // Generates the custom OSR entrypoint and sets the osr_pc_offset. |
| 307 void GenerateOsrPrologue(); | 277 void GenerateOsrPrologue(); |
| 308 | 278 |
| 309 enum SafepointMode { | 279 enum SafepointMode { |
| 310 RECORD_SIMPLE_SAFEPOINT, | 280 RECORD_SIMPLE_SAFEPOINT, |
| 311 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS | 281 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS |
| 312 }; | 282 }; |
| 313 | 283 |
| 314 void CallCode(Handle<Code> code, | 284 void CallCode(Handle<Code> code, |
| 315 RelocInfo::Mode mode, | 285 RelocInfo::Mode mode, |
| 316 LInstruction* instr); | 286 LInstruction* instr); |
| 317 | 287 |
| 318 void CallCodeGeneric(Handle<Code> code, | 288 void CallCodeGeneric(Handle<Code> code, |
| 319 RelocInfo::Mode mode, | 289 RelocInfo::Mode mode, |
| 320 LInstruction* instr, | 290 LInstruction* instr, |
| 321 SafepointMode safepoint_mode); | 291 SafepointMode safepoint_mode); |
| 322 | 292 |
| 323 void CallRuntime(const Runtime::Function* function, | 293 void CallRuntime(const Runtime::Function* function, |
| 324 int num_arguments, | 294 int num_arguments, |
| 325 LInstruction* instr); | 295 LInstruction* instr, |
| 296 SaveFPRegsMode save_doubles = kDontSaveFPRegs); |
| 326 | 297 |
| 327 void CallRuntime(Runtime::FunctionId id, | 298 void CallRuntime(Runtime::FunctionId id, |
| 328 int num_arguments, | 299 int num_arguments, |
| 329 LInstruction* instr) { | 300 LInstruction* instr) { |
| 330 const Runtime::Function* function = Runtime::FunctionForId(id); | 301 const Runtime::Function* function = Runtime::FunctionForId(id); |
| 331 CallRuntime(function, num_arguments, instr); | 302 CallRuntime(function, num_arguments, instr); |
| 332 } | 303 } |
| 333 | 304 |
| 334 void CallRuntimeFromDeferred(Runtime::FunctionId id, | 305 void CallRuntimeFromDeferred(Runtime::FunctionId id, |
| 335 int argc, | 306 int argc, |
| 336 LInstruction* instr); | 307 LInstruction* instr); |
| 337 | 308 |
| 338 // Generate a direct call to a known function. | 309 // Generate a direct call to a known function. |
| 339 // If the function is already loaded into x1 by the caller, function_reg may | 310 // If the function is already loaded into x1 by the caller, function_reg may |
| 340 // be set to x1. Otherwise, it must be NoReg, and CallKnownFunction will | 311 // be set to x1. Otherwise, it must be NoReg, and CallKnownFunction will |
| 341 // automatically load it. | 312 // automatically load it. |
| 342 void CallKnownFunction(Handle<JSFunction> function, | 313 void CallKnownFunction(Handle<JSFunction> function, |
| 343 int formal_parameter_count, | 314 int formal_parameter_count, |
| 344 int arity, | 315 int arity, |
| 345 LInstruction* instr, | 316 LInstruction* instr, |
| 346 CallKind call_kind, | 317 CallKind call_kind, |
| 347 Register function_reg = NoReg); | 318 Register function_reg = NoReg); |
| 348 | 319 |
| 349 // Support for recording safepoint and position information. | 320 // Support for recording safepoint and position information. |
| 350 void RecordPosition(int position); | 321 void RecordPosition(int position); |
| 351 void RecordAndUpdatePosition(int position); | 322 void RecordAndUpdatePosition(int position) V8_OVERRIDE; |
| 352 void RecordSafepoint(LPointerMap* pointers, | 323 void RecordSafepoint(LPointerMap* pointers, |
| 353 Safepoint::Kind kind, | 324 Safepoint::Kind kind, |
| 354 int arguments, | 325 int arguments, |
| 355 Safepoint::DeoptMode mode); | 326 Safepoint::DeoptMode mode); |
| 356 void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode); | 327 void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode); |
| 357 void RecordSafepoint(Safepoint::DeoptMode mode); | 328 void RecordSafepoint(Safepoint::DeoptMode mode); |
| 358 void RecordSafepointWithRegisters(LPointerMap* pointers, | 329 void RecordSafepointWithRegisters(LPointerMap* pointers, |
| 359 int arguments, | 330 int arguments, |
| 360 Safepoint::DeoptMode mode); | 331 Safepoint::DeoptMode mode); |
| 361 void RecordSafepointWithRegistersAndDoubles(LPointerMap* pointers, | 332 void RecordSafepointWithRegistersAndDoubles(LPointerMap* pointers, |
| 362 int arguments, | 333 int arguments, |
| 363 Safepoint::DeoptMode mode); | 334 Safepoint::DeoptMode mode); |
| 364 void RecordSafepointWithLazyDeopt(LInstruction* instr, | 335 void RecordSafepointWithLazyDeopt(LInstruction* instr, |
| 365 SafepointMode safepoint_mode); | 336 SafepointMode safepoint_mode); |
| 366 | 337 |
| 367 void EnsureSpaceForLazyDeopt(); | 338 void EnsureSpaceForLazyDeopt(int space_needed) V8_OVERRIDE; |
| 368 | 339 |
| 369 Zone* zone_; | |
| 370 LPlatformChunk* const chunk_; | |
| 371 MacroAssembler* const masm_; | |
| 372 CompilationInfo* const info_; | |
| 373 | |
| 374 int current_block_; | |
| 375 int current_instruction_; | |
| 376 const ZoneList<LInstruction*>* instructions_; | |
| 377 ZoneList<LEnvironment*> deoptimizations_; | 340 ZoneList<LEnvironment*> deoptimizations_; |
| 378 ZoneList<Deoptimizer::JumpTableEntry> deopt_jump_table_; | 341 ZoneList<Deoptimizer::JumpTableEntry> deopt_jump_table_; |
| 379 ZoneList<Handle<Object> > deoptimization_literals_; | 342 ZoneList<Handle<Object> > deoptimization_literals_; |
| 380 int inlined_function_count_; | 343 int inlined_function_count_; |
| 381 Scope* const scope_; | 344 Scope* const scope_; |
| 382 Status status_; | |
| 383 TranslationBuffer translations_; | 345 TranslationBuffer translations_; |
| 384 ZoneList<LDeferredCode*> deferred_; | 346 ZoneList<LDeferredCode*> deferred_; |
| 385 int osr_pc_offset_; | 347 int osr_pc_offset_; |
| 386 int last_lazy_deopt_pc_; | |
| 387 bool frame_is_built_; | 348 bool frame_is_built_; |
| 388 | 349 |
| 389 // Builder that keeps track of safepoints in the code. The table itself is | 350 // Builder that keeps track of safepoints in the code. The table itself is |
| 390 // emitted at the end of the generated code. | 351 // emitted at the end of the generated code. |
| 391 SafepointTableBuilder safepoints_; | 352 SafepointTableBuilder safepoints_; |
| 392 | 353 |
| 393 // Compiler from a set of parallel moves to a sequential list of moves. | 354 // Compiler from a set of parallel moves to a sequential list of moves. |
| 394 LGapResolver resolver_; | 355 LGapResolver resolver_; |
| 395 | 356 |
| 396 Safepoint::Kind expected_safepoint_kind_; | 357 Safepoint::Kind expected_safepoint_kind_; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 | 457 |
| 497 protected: | 458 protected: |
| 498 MacroAssembler* masm() const { return codegen_->masm(); } | 459 MacroAssembler* masm() const { return codegen_->masm(); } |
| 499 | 460 |
| 500 LCodeGen* codegen_; | 461 LCodeGen* codegen_; |
| 501 }; | 462 }; |
| 502 | 463 |
| 503 } } // namespace v8::internal | 464 } } // namespace v8::internal |
| 504 | 465 |
| 505 #endif // V8_A64_LITHIUM_CODEGEN_A64_H_ | 466 #endif // V8_A64_LITHIUM_CODEGEN_A64_H_ |
| OLD | NEW |