| 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 |