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 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 } \ | 367 } \ |
368 } \ | 368 } \ |
369 } \ | 369 } \ |
370 } while (0) | 370 } while (0) |
371 | 371 |
372 void CodeGenerator::AssembleDeconstructFrame() { | 372 void CodeGenerator::AssembleDeconstructFrame() { |
373 __ mov(esp, ebp); | 373 __ mov(esp, ebp); |
374 __ pop(ebp); | 374 __ pop(ebp); |
375 } | 375 } |
376 | 376 |
377 // For insert fninit/fld1 instructions after the Prologue | |
378 thread_local bool is_block_0 = false; | |
379 | |
380 void CodeGenerator::AssembleSetupStackPointer() { is_block_0 = true; } | |
381 | |
382 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { | 377 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { |
383 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); | 378 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); |
384 if (sp_slot_delta > 0) { | 379 if (sp_slot_delta > 0) { |
385 __ add(esp, Immediate(sp_slot_delta * kPointerSize)); | 380 __ add(esp, Immediate(sp_slot_delta * kPointerSize)); |
386 } | 381 } |
387 frame_access_state()->SetFrameAccessToDefault(); | 382 frame_access_state()->SetFrameAccessToDefault(); |
388 } | 383 } |
389 | 384 |
390 | 385 |
391 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { | 386 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 | 432 |
438 __ bind(&done); | 433 __ bind(&done); |
439 } | 434 } |
440 | 435 |
441 // Assembles an instruction after register allocation, producing machine code. | 436 // Assembles an instruction after register allocation, producing machine code. |
442 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 437 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
443 X87OperandConverter i(this, instr); | 438 X87OperandConverter i(this, instr); |
444 InstructionCode opcode = instr->opcode(); | 439 InstructionCode opcode = instr->opcode(); |
445 ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode); | 440 ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode); |
446 | 441 |
447 // Workaround for CL #35139 (https://codereview.chromium.org/1775323002) | |
448 if (is_block_0) { | |
449 __ fninit(); | |
450 __ fld1(); | |
451 is_block_0 = false; | |
452 } | |
453 | |
454 switch (arch_opcode) { | 442 switch (arch_opcode) { |
455 case kArchCallCodeObject: { | 443 case kArchCallCodeObject: { |
456 if (FLAG_debug_code && FLAG_enable_slow_asserts) { | 444 if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
457 __ VerifyX87StackDepth(1); | 445 __ VerifyX87StackDepth(1); |
458 } | 446 } |
459 __ fstp(0); | 447 __ fstp(0); |
460 EnsureSpaceForLazyDeopt(); | 448 EnsureSpaceForLazyDeopt(); |
461 if (HasImmediateInput(instr, 0)) { | 449 if (HasImmediateInput(instr, 0)) { |
462 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); | 450 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); |
463 __ call(code, RelocInfo::CODE_TARGET); | 451 __ call(code, RelocInfo::CODE_TARGET); |
(...skipping 1657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2121 // ^ esp ^ ebp | 2109 // ^ esp ^ ebp |
2122 | 2110 |
2123 // --{ mov esp, ebp }----------------------------------------------------------- | 2111 // --{ mov esp, ebp }----------------------------------------------------------- |
2124 // | FP | RET | args | caller frame | | 2112 // | FP | RET | args | caller frame | |
2125 // ^ esp,ebp | 2113 // ^ esp,ebp |
2126 | 2114 |
2127 // --{ pop ebp }---------------------------------------------------------------- | 2115 // --{ pop ebp }---------------------------------------------------------------- |
2128 // | RET | args | caller frame | | 2116 // | RET | args | caller frame | |
2129 // ^ esp ^ ebp | 2117 // ^ esp ^ ebp |
2130 | 2118 |
| 2119 void CodeGenerator::FinishFrame(Frame* frame) { |
| 2120 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
| 2121 const RegList saves = descriptor->CalleeSavedRegisters(); |
| 2122 if (saves != 0) { // Save callee-saved registers. |
| 2123 DCHECK(!info()->is_osr()); |
| 2124 int pushed = 0; |
| 2125 for (int i = Register::kNumRegisters - 1; i >= 0; i--) { |
| 2126 if (!((1 << i) & saves)) continue; |
| 2127 ++pushed; |
| 2128 } |
| 2129 frame->AllocateSavedCalleeRegisterSlots(pushed); |
| 2130 } |
2131 | 2131 |
2132 void CodeGenerator::AssemblePrologue() { | 2132 // Initailize FPU state. |
| 2133 __ fninit(); |
| 2134 __ fld1(); |
| 2135 } |
| 2136 |
| 2137 void CodeGenerator::AssembleConstructFrame() { |
2133 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 2138 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
2134 if (frame_access_state()->has_frame()) { | 2139 if (frame_access_state()->has_frame()) { |
2135 if (descriptor->IsCFunctionCall()) { | 2140 if (descriptor->IsCFunctionCall()) { |
2136 __ push(ebp); | 2141 __ push(ebp); |
2137 __ mov(ebp, esp); | 2142 __ mov(ebp, esp); |
2138 } else if (descriptor->IsJSFunctionCall()) { | 2143 } else if (descriptor->IsJSFunctionCall()) { |
2139 __ Prologue(this->info()->GeneratePreagedPrologue()); | 2144 __ Prologue(this->info()->GeneratePreagedPrologue()); |
2140 } else { | 2145 } else { |
2141 __ StubPrologue(info()->GetOutputStackFrameType()); | 2146 __ StubPrologue(info()->GetOutputStackFrameType()); |
2142 } | 2147 } |
2143 } | 2148 } |
2144 int stack_shrink_slots = frame()->GetSpillSlotCount(); | 2149 |
| 2150 int shrink_slots = frame()->GetSpillSlotCount(); |
| 2151 |
2145 if (info()->is_osr()) { | 2152 if (info()->is_osr()) { |
2146 // TurboFan OSR-compiled functions cannot be entered directly. | 2153 // TurboFan OSR-compiled functions cannot be entered directly. |
2147 __ Abort(kShouldNotDirectlyEnterOsrFunction); | 2154 __ Abort(kShouldNotDirectlyEnterOsrFunction); |
2148 | 2155 |
2149 // Unoptimized code jumps directly to this entrypoint while the unoptimized | 2156 // Unoptimized code jumps directly to this entrypoint while the unoptimized |
2150 // frame is still on the stack. Optimized code uses OSR values directly from | 2157 // frame is still on the stack. Optimized code uses OSR values directly from |
2151 // the unoptimized frame. Thus, all that needs to be done is to allocate the | 2158 // the unoptimized frame. Thus, all that needs to be done is to allocate the |
2152 // remaining stack slots. | 2159 // remaining stack slots. |
2153 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); | 2160 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); |
2154 osr_pc_offset_ = __ pc_offset(); | 2161 osr_pc_offset_ = __ pc_offset(); |
2155 stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots(); | 2162 shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots(); |
2156 | 2163 |
2157 // Initailize FPU state. | 2164 // Initailize FPU state. |
2158 __ fninit(); | 2165 __ fninit(); |
2159 __ fld1(); | 2166 __ fld1(); |
2160 } | 2167 } |
2161 | 2168 |
2162 const RegList saves = descriptor->CalleeSavedRegisters(); | 2169 const RegList saves = descriptor->CalleeSavedRegisters(); |
2163 if (stack_shrink_slots > 0) { | 2170 if (shrink_slots > 0) { |
2164 __ sub(esp, Immediate(stack_shrink_slots * kPointerSize)); | 2171 __ sub(esp, Immediate(shrink_slots * kPointerSize)); |
2165 } | 2172 } |
2166 | 2173 |
2167 if (saves != 0) { // Save callee-saved registers. | 2174 if (saves != 0) { // Save callee-saved registers. |
2168 DCHECK(!info()->is_osr()); | 2175 DCHECK(!info()->is_osr()); |
2169 int pushed = 0; | 2176 int pushed = 0; |
2170 for (int i = Register::kNumRegisters - 1; i >= 0; i--) { | 2177 for (int i = Register::kNumRegisters - 1; i >= 0; i--) { |
2171 if (!((1 << i) & saves)) continue; | 2178 if (!((1 << i) & saves)) continue; |
2172 __ push(Register::from_code(i)); | 2179 __ push(Register::from_code(i)); |
2173 ++pushed; | 2180 ++pushed; |
2174 } | 2181 } |
2175 frame()->AllocateSavedCalleeRegisterSlots(pushed); | |
2176 } | 2182 } |
2177 } | 2183 } |
2178 | 2184 |
2179 | 2185 |
2180 void CodeGenerator::AssembleReturn() { | 2186 void CodeGenerator::AssembleReturn() { |
2181 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 2187 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
2182 | 2188 |
2183 // Clear the FPU stack only if there is no return value in the stack. | 2189 // Clear the FPU stack only if there is no return value in the stack. |
2184 if (FLAG_debug_code && FLAG_enable_slow_asserts) { | 2190 if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
2185 __ VerifyX87StackDepth(1); | 2191 __ VerifyX87StackDepth(1); |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2460 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; | 2466 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; |
2461 __ Nop(padding_size); | 2467 __ Nop(padding_size); |
2462 } | 2468 } |
2463 } | 2469 } |
2464 | 2470 |
2465 #undef __ | 2471 #undef __ |
2466 | 2472 |
2467 } // namespace compiler | 2473 } // namespace compiler |
2468 } // namespace internal | 2474 } // namespace internal |
2469 } // namespace v8 | 2475 } // namespace v8 |
OLD | NEW |