| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
| 6 | 6 |
| 7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
| 8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
| 9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
| 10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 if (sp_slot_delta < 0) { | 353 if (sp_slot_delta < 0) { |
| 354 __ sub(esp, Immediate(-sp_slot_delta * kPointerSize)); | 354 __ sub(esp, Immediate(-sp_slot_delta * kPointerSize)); |
| 355 frame_access_state()->IncreaseSPDelta(-sp_slot_delta); | 355 frame_access_state()->IncreaseSPDelta(-sp_slot_delta); |
| 356 } | 356 } |
| 357 if (frame()->needs_frame()) { | 357 if (frame()->needs_frame()) { |
| 358 __ mov(ebp, MemOperand(ebp, 0)); | 358 __ mov(ebp, MemOperand(ebp, 0)); |
| 359 } | 359 } |
| 360 frame_access_state()->SetFrameAccessToSP(); | 360 frame_access_state()->SetFrameAccessToSP(); |
| 361 } | 361 } |
| 362 | 362 |
| 363 thread_local bool is_handler_entry_point = false; |
| 364 static void DoEnsureSpaceForLazyDeopt(CompilationInfo* info, |
| 365 MacroAssembler* masm, |
| 366 int last_lazy_deopt_pc) { |
| 367 if (!info->ShouldEnsureSpaceForLazyDeopt()) { |
| 368 return; |
| 369 } |
| 370 |
| 371 int space_needed = Deoptimizer::patch_size(); |
| 372 // Ensure that we have enough space after the previous lazy-bailout |
| 373 // instruction for patching the code here. |
| 374 int current_pc = masm->pc_offset(); |
| 375 if (current_pc < last_lazy_deopt_pc + space_needed) { |
| 376 int padding_size = last_lazy_deopt_pc + space_needed - current_pc; |
| 377 masm->Nop(padding_size); |
| 378 } |
| 379 } |
| 363 | 380 |
| 364 // Assembles an instruction after register allocation, producing machine code. | 381 // Assembles an instruction after register allocation, producing machine code. |
| 365 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 382 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
| 366 X87OperandConverter i(this, instr); | 383 X87OperandConverter i(this, instr); |
| 384 if (is_handler_entry_point) { |
| 385 // Lazy Bailout entry, need to re-initialize FPU state. |
| 386 __ fninit(); |
| 387 __ fld1(); |
| 388 is_handler_entry_point = false; |
| 389 } |
| 367 | 390 |
| 368 switch (ArchOpcodeField::decode(instr->opcode())) { | 391 switch (ArchOpcodeField::decode(instr->opcode())) { |
| 369 case kArchCallCodeObject: { | 392 case kArchCallCodeObject: { |
| 393 DoEnsureSpaceForLazyDeopt(info(), masm(), last_lazy_deopt_pc_); |
| 370 if (FLAG_debug_code && FLAG_enable_slow_asserts) { | 394 if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
| 371 __ VerifyX87StackDepth(1); | 395 __ VerifyX87StackDepth(1); |
| 372 } | 396 } |
| 373 __ fstp(0); | 397 __ fstp(0); |
| 374 EnsureSpaceForLazyDeopt(); | |
| 375 if (HasImmediateInput(instr, 0)) { | 398 if (HasImmediateInput(instr, 0)) { |
| 376 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); | 399 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); |
| 377 __ call(code, RelocInfo::CODE_TARGET); | 400 __ call(code, RelocInfo::CODE_TARGET); |
| 378 } else { | 401 } else { |
| 379 Register reg = i.InputRegister(0); | 402 Register reg = i.InputRegister(0); |
| 380 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 403 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
| 381 __ call(reg); | 404 __ call(reg); |
| 382 } | 405 } |
| 383 RecordCallPosition(instr); | 406 RecordCallPosition(instr); |
| 384 bool double_result = | 407 bool double_result = |
| (...skipping 24 matching lines...) Expand all Loading... |
| 409 __ jmp(code, RelocInfo::CODE_TARGET); | 432 __ jmp(code, RelocInfo::CODE_TARGET); |
| 410 } else { | 433 } else { |
| 411 Register reg = i.InputRegister(0); | 434 Register reg = i.InputRegister(0); |
| 412 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 435 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
| 413 __ jmp(reg); | 436 __ jmp(reg); |
| 414 } | 437 } |
| 415 frame_access_state()->ClearSPDelta(); | 438 frame_access_state()->ClearSPDelta(); |
| 416 break; | 439 break; |
| 417 } | 440 } |
| 418 case kArchCallJSFunction: { | 441 case kArchCallJSFunction: { |
| 419 EnsureSpaceForLazyDeopt(); | 442 DoEnsureSpaceForLazyDeopt(info(), masm(), last_lazy_deopt_pc_); |
| 420 Register func = i.InputRegister(0); | 443 Register func = i.InputRegister(0); |
| 421 if (FLAG_debug_code) { | 444 if (FLAG_debug_code) { |
| 422 // Check the function's context matches the context argument. | 445 // Check the function's context matches the context argument. |
| 423 __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset)); | 446 __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset)); |
| 424 __ Assert(equal, kWrongFunctionContext); | 447 __ Assert(equal, kWrongFunctionContext); |
| 425 } | 448 } |
| 426 if (FLAG_debug_code && FLAG_enable_slow_asserts) { | 449 if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
| 427 __ VerifyX87StackDepth(1); | 450 __ VerifyX87StackDepth(1); |
| 428 } | 451 } |
| 429 __ fstp(0); | 452 __ fstp(0); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 456 __ VerifyX87StackDepth(1); | 479 __ VerifyX87StackDepth(1); |
| 457 } | 480 } |
| 458 __ fstp(0); | 481 __ fstp(0); |
| 459 int stack_param_delta = i.InputInt32(instr->InputCount() - 1); | 482 int stack_param_delta = i.InputInt32(instr->InputCount() - 1); |
| 460 AssembleDeconstructActivationRecord(stack_param_delta); | 483 AssembleDeconstructActivationRecord(stack_param_delta); |
| 461 __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset)); | 484 __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset)); |
| 462 frame_access_state()->ClearSPDelta(); | 485 frame_access_state()->ClearSPDelta(); |
| 463 break; | 486 break; |
| 464 } | 487 } |
| 465 case kArchLazyBailout: { | 488 case kArchLazyBailout: { |
| 466 EnsureSpaceForLazyDeopt(); | 489 DoEnsureSpaceForLazyDeopt(info(), masm(), last_lazy_deopt_pc_); |
| 467 RecordCallPosition(instr); | 490 RecordCallPosition(instr); |
| 468 // Lazy Bailout entry, need to re-initialize FPU state. | 491 // Lazy Bailout entry, need to re-initialize FPU state. |
| 469 __ fninit(); | 492 __ fninit(); |
| 470 __ fld1(); | 493 __ fld1(); |
| 471 break; | 494 break; |
| 472 } | 495 } |
| 473 case kArchPrepareCallCFunction: { | 496 case kArchPrepareCallCFunction: { |
| 474 // Frame alignment requires using FP-relative frame addressing. | 497 // Frame alignment requires using FP-relative frame addressing. |
| 475 frame_access_state()->SetFrameAccessToFP(); | 498 frame_access_state()->SetFrameAccessToFP(); |
| 476 int const num_parameters = MiscField::decode(instr->opcode()); | 499 int const num_parameters = MiscField::decode(instr->opcode()); |
| (...skipping 1672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2149 for (size_t index = 0; index < target_count; ++index) { | 2172 for (size_t index = 0; index < target_count; ++index) { |
| 2150 __ dd(targets[index]); | 2173 __ dd(targets[index]); |
| 2151 } | 2174 } |
| 2152 } | 2175 } |
| 2153 | 2176 |
| 2154 | 2177 |
| 2155 void CodeGenerator::AddNopForSmiCodeInlining() { __ nop(); } | 2178 void CodeGenerator::AddNopForSmiCodeInlining() { __ nop(); } |
| 2156 | 2179 |
| 2157 | 2180 |
| 2158 void CodeGenerator::EnsureSpaceForLazyDeopt() { | 2181 void CodeGenerator::EnsureSpaceForLazyDeopt() { |
| 2159 if (!info()->ShouldEnsureSpaceForLazyDeopt()) { | 2182 is_handler_entry_point = true; |
| 2160 return; | 2183 DoEnsureSpaceForLazyDeopt(info(), masm(), last_lazy_deopt_pc_); |
| 2161 } | |
| 2162 | |
| 2163 int space_needed = Deoptimizer::patch_size(); | |
| 2164 // Ensure that we have enough space after the previous lazy-bailout | |
| 2165 // instruction for patching the code here. | |
| 2166 int current_pc = masm()->pc_offset(); | |
| 2167 if (current_pc < last_lazy_deopt_pc_ + space_needed) { | |
| 2168 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; | |
| 2169 __ Nop(padding_size); | |
| 2170 } | |
| 2171 } | 2184 } |
| 2172 | 2185 |
| 2173 #undef __ | 2186 #undef __ |
| 2174 | 2187 |
| 2175 } // namespace compiler | 2188 } // namespace compiler |
| 2176 } // namespace internal | 2189 } // namespace internal |
| 2177 } // namespace v8 | 2190 } // namespace v8 |
| OLD | NEW |