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 } | |
380 | 363 |
381 // Assembles an instruction after register allocation, producing machine code. | 364 // Assembles an instruction after register allocation, producing machine code. |
382 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 365 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
383 X87OperandConverter i(this, instr); | 366 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 } | |
390 | 367 |
391 switch (ArchOpcodeField::decode(instr->opcode())) { | 368 switch (ArchOpcodeField::decode(instr->opcode())) { |
392 case kArchCallCodeObject: { | 369 case kArchCallCodeObject: { |
393 DoEnsureSpaceForLazyDeopt(info(), masm(), last_lazy_deopt_pc_); | |
394 if (FLAG_debug_code && FLAG_enable_slow_asserts) { | 370 if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
395 __ VerifyX87StackDepth(1); | 371 __ VerifyX87StackDepth(1); |
396 } | 372 } |
397 __ fstp(0); | 373 __ fstp(0); |
| 374 EnsureSpaceForLazyDeopt(); |
398 if (HasImmediateInput(instr, 0)) { | 375 if (HasImmediateInput(instr, 0)) { |
399 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); | 376 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); |
400 __ call(code, RelocInfo::CODE_TARGET); | 377 __ call(code, RelocInfo::CODE_TARGET); |
401 } else { | 378 } else { |
402 Register reg = i.InputRegister(0); | 379 Register reg = i.InputRegister(0); |
403 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 380 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
404 __ call(reg); | 381 __ call(reg); |
405 } | 382 } |
406 RecordCallPosition(instr); | 383 RecordCallPosition(instr); |
407 bool double_result = | 384 bool double_result = |
(...skipping 24 matching lines...) Expand all Loading... |
432 __ jmp(code, RelocInfo::CODE_TARGET); | 409 __ jmp(code, RelocInfo::CODE_TARGET); |
433 } else { | 410 } else { |
434 Register reg = i.InputRegister(0); | 411 Register reg = i.InputRegister(0); |
435 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 412 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
436 __ jmp(reg); | 413 __ jmp(reg); |
437 } | 414 } |
438 frame_access_state()->ClearSPDelta(); | 415 frame_access_state()->ClearSPDelta(); |
439 break; | 416 break; |
440 } | 417 } |
441 case kArchCallJSFunction: { | 418 case kArchCallJSFunction: { |
442 DoEnsureSpaceForLazyDeopt(info(), masm(), last_lazy_deopt_pc_); | 419 EnsureSpaceForLazyDeopt(); |
443 Register func = i.InputRegister(0); | 420 Register func = i.InputRegister(0); |
444 if (FLAG_debug_code) { | 421 if (FLAG_debug_code) { |
445 // Check the function's context matches the context argument. | 422 // Check the function's context matches the context argument. |
446 __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset)); | 423 __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset)); |
447 __ Assert(equal, kWrongFunctionContext); | 424 __ Assert(equal, kWrongFunctionContext); |
448 } | 425 } |
449 if (FLAG_debug_code && FLAG_enable_slow_asserts) { | 426 if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
450 __ VerifyX87StackDepth(1); | 427 __ VerifyX87StackDepth(1); |
451 } | 428 } |
452 __ fstp(0); | 429 __ fstp(0); |
(...skipping 1779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2232 for (size_t index = 0; index < target_count; ++index) { | 2209 for (size_t index = 0; index < target_count; ++index) { |
2233 __ dd(targets[index]); | 2210 __ dd(targets[index]); |
2234 } | 2211 } |
2235 } | 2212 } |
2236 | 2213 |
2237 | 2214 |
2238 void CodeGenerator::AddNopForSmiCodeInlining() { __ nop(); } | 2215 void CodeGenerator::AddNopForSmiCodeInlining() { __ nop(); } |
2239 | 2216 |
2240 | 2217 |
2241 void CodeGenerator::EnsureSpaceForLazyDeopt() { | 2218 void CodeGenerator::EnsureSpaceForLazyDeopt() { |
2242 is_handler_entry_point = true; | 2219 if (!info()->ShouldEnsureSpaceForLazyDeopt()) { |
2243 DoEnsureSpaceForLazyDeopt(info(), masm(), last_lazy_deopt_pc_); | 2220 return; |
| 2221 } |
| 2222 |
| 2223 int space_needed = Deoptimizer::patch_size(); |
| 2224 // Ensure that we have enough space after the previous lazy-bailout |
| 2225 // instruction for patching the code here. |
| 2226 int current_pc = masm()->pc_offset(); |
| 2227 if (current_pc < last_lazy_deopt_pc_ + space_needed) { |
| 2228 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; |
| 2229 __ Nop(padding_size); |
| 2230 } |
2244 } | 2231 } |
2245 | 2232 |
2246 #undef __ | 2233 #undef __ |
2247 | 2234 |
2248 } // namespace compiler | 2235 } // namespace compiler |
2249 } // namespace internal | 2236 } // namespace internal |
2250 } // namespace v8 | 2237 } // namespace v8 |
OLD | NEW |