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 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 Label done; \ | 330 Label done; \ |
331 __ j(above_equal, &done, Label::kNear); \ | 331 __ j(above_equal, &done, Label::kNear); \ |
332 if (instr->InputAt(2)->IsRegister()) { \ | 332 if (instr->InputAt(2)->IsRegister()) { \ |
333 __ asm_instr(i.MemoryOperand(3), i.InputRegister(2)); \ | 333 __ asm_instr(i.MemoryOperand(3), i.InputRegister(2)); \ |
334 } else { \ | 334 } else { \ |
335 __ asm_instr(i.MemoryOperand(3), i.InputImmediate(2)); \ | 335 __ asm_instr(i.MemoryOperand(3), i.InputImmediate(2)); \ |
336 } \ | 336 } \ |
337 __ bind(&done); \ | 337 __ bind(&done); \ |
338 } while (false) | 338 } while (false) |
339 | 339 |
| 340 void CodeGenerator::AssembleDeconstructFrame() { |
| 341 __ mov(esp, ebp); |
| 342 __ pop(ebp); |
| 343 } |
| 344 |
| 345 // For insert fninit/fld1 instructions after the Prologue |
| 346 thread_local bool is_block_0 = false; |
| 347 |
| 348 void CodeGenerator::AssembleSetupStackPointer() { is_block_0 = true; } |
340 | 349 |
341 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { | 350 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { |
342 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); | 351 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); |
343 if (sp_slot_delta > 0) { | 352 if (sp_slot_delta > 0) { |
344 __ add(esp, Immediate(sp_slot_delta * kPointerSize)); | 353 __ add(esp, Immediate(sp_slot_delta * kPointerSize)); |
345 } | 354 } |
346 frame_access_state()->SetFrameAccessToDefault(); | 355 frame_access_state()->SetFrameAccessToDefault(); |
347 } | 356 } |
348 | 357 |
349 | 358 |
350 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { | 359 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { |
351 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); | 360 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); |
352 if (sp_slot_delta < 0) { | 361 if (sp_slot_delta < 0) { |
353 __ sub(esp, Immediate(-sp_slot_delta * kPointerSize)); | 362 __ sub(esp, Immediate(-sp_slot_delta * kPointerSize)); |
354 frame_access_state()->IncreaseSPDelta(-sp_slot_delta); | 363 frame_access_state()->IncreaseSPDelta(-sp_slot_delta); |
355 } | 364 } |
356 if (frame()->needs_frame()) { | 365 if (frame_access_state()->has_frame()) { |
357 __ mov(ebp, MemOperand(ebp, 0)); | 366 __ mov(ebp, MemOperand(ebp, 0)); |
358 } | 367 } |
359 frame_access_state()->SetFrameAccessToSP(); | 368 frame_access_state()->SetFrameAccessToSP(); |
360 } | 369 } |
361 | 370 |
362 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg, | 371 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg, |
363 Register, Register, | 372 Register, Register, |
364 Register) { | 373 Register) { |
365 // There are not enough temp registers left on ia32 for a call instruction | 374 // There are not enough temp registers left on ia32 for a call instruction |
366 // so we pick some scratch registers and save/restore them manually here. | 375 // so we pick some scratch registers and save/restore them manually here. |
(...skipping 28 matching lines...) Expand all Loading... |
395 __ pop(scratch1); | 404 __ pop(scratch1); |
396 | 405 |
397 __ bind(&done); | 406 __ bind(&done); |
398 } | 407 } |
399 | 408 |
400 // Assembles an instruction after register allocation, producing machine code. | 409 // Assembles an instruction after register allocation, producing machine code. |
401 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 410 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
402 X87OperandConverter i(this, instr); | 411 X87OperandConverter i(this, instr); |
403 InstructionCode opcode = instr->opcode(); | 412 InstructionCode opcode = instr->opcode(); |
404 ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode); | 413 ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode); |
| 414 |
| 415 // Workaround for CL #35139 (https://codereview.chromium.org/1775323002) |
| 416 if (is_block_0) { |
| 417 __ fninit(); |
| 418 __ fld1(); |
| 419 is_block_0 = false; |
| 420 } |
| 421 |
405 switch (arch_opcode) { | 422 switch (arch_opcode) { |
406 case kArchCallCodeObject: { | 423 case kArchCallCodeObject: { |
407 if (FLAG_debug_code && FLAG_enable_slow_asserts) { | 424 if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
408 __ VerifyX87StackDepth(1); | 425 __ VerifyX87StackDepth(1); |
409 } | 426 } |
410 __ fstp(0); | 427 __ fstp(0); |
411 EnsureSpaceForLazyDeopt(); | 428 EnsureSpaceForLazyDeopt(); |
412 if (HasImmediateInput(instr, 0)) { | 429 if (HasImmediateInput(instr, 0)) { |
413 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); | 430 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); |
414 __ call(code, RelocInfo::CODE_TARGET); | 431 __ call(code, RelocInfo::CODE_TARGET); |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
592 case kArchRet: | 609 case kArchRet: |
593 AssembleReturn(); | 610 AssembleReturn(); |
594 break; | 611 break; |
595 case kArchFramePointer: | 612 case kArchFramePointer: |
596 __ mov(i.OutputRegister(), ebp); | 613 __ mov(i.OutputRegister(), ebp); |
597 break; | 614 break; |
598 case kArchStackPointer: | 615 case kArchStackPointer: |
599 __ mov(i.OutputRegister(), esp); | 616 __ mov(i.OutputRegister(), esp); |
600 break; | 617 break; |
601 case kArchParentFramePointer: | 618 case kArchParentFramePointer: |
602 if (frame_access_state()->frame()->needs_frame()) { | 619 if (frame_access_state()->has_frame()) { |
603 __ mov(i.OutputRegister(), Operand(ebp, 0)); | 620 __ mov(i.OutputRegister(), Operand(ebp, 0)); |
604 } else { | 621 } else { |
605 __ mov(i.OutputRegister(), ebp); | 622 __ mov(i.OutputRegister(), ebp); |
606 } | 623 } |
607 break; | 624 break; |
608 case kArchTruncateDoubleToI: { | 625 case kArchTruncateDoubleToI: { |
609 if (!instr->InputAt(0)->IsDoubleRegister()) { | 626 if (!instr->InputAt(0)->IsDoubleRegister()) { |
610 __ fld_d(i.InputOperand(0)); | 627 __ fld_d(i.InputOperand(0)); |
611 } | 628 } |
612 __ TruncateX87TOSToI(i.OutputRegister()); | 629 __ TruncateX87TOSToI(i.OutputRegister()); |
(...skipping 1461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2074 // | FP | RET | args | caller frame | | 2091 // | FP | RET | args | caller frame | |
2075 // ^ esp,ebp | 2092 // ^ esp,ebp |
2076 | 2093 |
2077 // --{ pop ebp }---------------------------------------------------------------- | 2094 // --{ pop ebp }---------------------------------------------------------------- |
2078 // | RET | args | caller frame | | 2095 // | RET | args | caller frame | |
2079 // ^ esp ^ ebp | 2096 // ^ esp ^ ebp |
2080 | 2097 |
2081 | 2098 |
2082 void CodeGenerator::AssemblePrologue() { | 2099 void CodeGenerator::AssemblePrologue() { |
2083 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 2100 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
2084 if (frame()->needs_frame()) { | 2101 if (frame_access_state()->has_frame()) { |
2085 if (descriptor->IsCFunctionCall()) { | 2102 if (descriptor->IsCFunctionCall()) { |
2086 __ push(ebp); | 2103 __ push(ebp); |
2087 __ mov(ebp, esp); | 2104 __ mov(ebp, esp); |
2088 } else if (descriptor->IsJSFunctionCall()) { | 2105 } else if (descriptor->IsJSFunctionCall()) { |
2089 __ Prologue(this->info()->GeneratePreagedPrologue()); | 2106 __ Prologue(this->info()->GeneratePreagedPrologue()); |
2090 } else { | 2107 } else { |
2091 __ StubPrologue(info()->GetOutputStackFrameType()); | 2108 __ StubPrologue(info()->GetOutputStackFrameType()); |
2092 } | 2109 } |
2093 } else { | |
2094 frame()->SetElidedFrameSizeInSlots(kPCOnStackSize / kPointerSize); | |
2095 } | 2110 } |
2096 frame_access_state()->SetFrameAccessToDefault(); | |
2097 | |
2098 int stack_shrink_slots = frame()->GetSpillSlotCount(); | 2111 int stack_shrink_slots = frame()->GetSpillSlotCount(); |
2099 if (info()->is_osr()) { | 2112 if (info()->is_osr()) { |
2100 // TurboFan OSR-compiled functions cannot be entered directly. | 2113 // TurboFan OSR-compiled functions cannot be entered directly. |
2101 __ Abort(kShouldNotDirectlyEnterOsrFunction); | 2114 __ Abort(kShouldNotDirectlyEnterOsrFunction); |
2102 | 2115 |
2103 // Unoptimized code jumps directly to this entrypoint while the unoptimized | 2116 // Unoptimized code jumps directly to this entrypoint while the unoptimized |
2104 // frame is still on the stack. Optimized code uses OSR values directly from | 2117 // frame is still on the stack. Optimized code uses OSR values directly from |
2105 // the unoptimized frame. Thus, all that needs to be done is to allocate the | 2118 // the unoptimized frame. Thus, all that needs to be done is to allocate the |
2106 // remaining stack slots. | 2119 // remaining stack slots. |
2107 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); | 2120 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); |
2108 osr_pc_offset_ = __ pc_offset(); | 2121 osr_pc_offset_ = __ pc_offset(); |
2109 stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots(); | 2122 stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots(); |
| 2123 |
| 2124 // Initailize FPU state. |
| 2125 __ fninit(); |
| 2126 __ fld1(); |
2110 } | 2127 } |
2111 | 2128 |
2112 const RegList saves = descriptor->CalleeSavedRegisters(); | 2129 const RegList saves = descriptor->CalleeSavedRegisters(); |
2113 if (stack_shrink_slots > 0) { | 2130 if (stack_shrink_slots > 0) { |
2114 __ sub(esp, Immediate(stack_shrink_slots * kPointerSize)); | 2131 __ sub(esp, Immediate(stack_shrink_slots * kPointerSize)); |
2115 } | 2132 } |
2116 | 2133 |
2117 if (saves != 0) { // Save callee-saved registers. | 2134 if (saves != 0) { // Save callee-saved registers. |
2118 DCHECK(!info()->is_osr()); | 2135 DCHECK(!info()->is_osr()); |
2119 int pushed = 0; | 2136 int pushed = 0; |
2120 for (int i = Register::kNumRegisters - 1; i >= 0; i--) { | 2137 for (int i = Register::kNumRegisters - 1; i >= 0; i--) { |
2121 if (!((1 << i) & saves)) continue; | 2138 if (!((1 << i) & saves)) continue; |
2122 __ push(Register::from_code(i)); | 2139 __ push(Register::from_code(i)); |
2123 ++pushed; | 2140 ++pushed; |
2124 } | 2141 } |
2125 frame()->AllocateSavedCalleeRegisterSlots(pushed); | 2142 frame()->AllocateSavedCalleeRegisterSlots(pushed); |
2126 } | 2143 } |
2127 | |
2128 // Initailize FPU state. | |
2129 __ fninit(); | |
2130 __ fld1(); | |
2131 } | 2144 } |
2132 | 2145 |
2133 | 2146 |
2134 void CodeGenerator::AssembleReturn() { | 2147 void CodeGenerator::AssembleReturn() { |
2135 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 2148 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
2136 | 2149 |
2137 // Clear the FPU stack only if there is no return value in the stack. | 2150 // Clear the FPU stack only if there is no return value in the stack. |
2138 if (FLAG_debug_code && FLAG_enable_slow_asserts) { | 2151 if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
2139 __ VerifyX87StackDepth(1); | 2152 __ VerifyX87StackDepth(1); |
2140 } | 2153 } |
(...skipping 12 matching lines...) Expand all Loading... |
2153 const RegList saves = descriptor->CalleeSavedRegisters(); | 2166 const RegList saves = descriptor->CalleeSavedRegisters(); |
2154 // Restore registers. | 2167 // Restore registers. |
2155 if (saves != 0) { | 2168 if (saves != 0) { |
2156 for (int i = 0; i < Register::kNumRegisters; i++) { | 2169 for (int i = 0; i < Register::kNumRegisters; i++) { |
2157 if (!((1 << i) & saves)) continue; | 2170 if (!((1 << i) & saves)) continue; |
2158 __ pop(Register::from_code(i)); | 2171 __ pop(Register::from_code(i)); |
2159 } | 2172 } |
2160 } | 2173 } |
2161 | 2174 |
2162 if (descriptor->IsCFunctionCall()) { | 2175 if (descriptor->IsCFunctionCall()) { |
2163 __ mov(esp, ebp); // Move stack pointer back to frame pointer. | 2176 AssembleDeconstructFrame(); |
2164 __ pop(ebp); // Pop caller's frame pointer. | 2177 } else if (frame_access_state()->has_frame()) { |
2165 } else if (frame()->needs_frame()) { | |
2166 // Canonicalize JSFunction return sites for now. | 2178 // Canonicalize JSFunction return sites for now. |
2167 if (return_label_.is_bound()) { | 2179 if (return_label_.is_bound()) { |
2168 __ jmp(&return_label_); | 2180 __ jmp(&return_label_); |
2169 return; | 2181 return; |
2170 } else { | 2182 } else { |
2171 __ bind(&return_label_); | 2183 __ bind(&return_label_); |
2172 __ mov(esp, ebp); // Move stack pointer back to frame pointer. | 2184 AssembleDeconstructFrame(); |
2173 __ pop(ebp); // Pop caller's frame pointer. | |
2174 } | 2185 } |
2175 } | 2186 } |
2176 if (pop_count == 0) { | 2187 if (pop_count == 0) { |
2177 __ ret(0); | 2188 __ ret(0); |
2178 } else { | 2189 } else { |
2179 __ Ret(pop_count * kPointerSize, ebx); | 2190 __ Ret(pop_count * kPointerSize, ebx); |
2180 } | 2191 } |
2181 } | 2192 } |
2182 | 2193 |
2183 | 2194 |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2416 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; | 2427 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; |
2417 __ Nop(padding_size); | 2428 __ Nop(padding_size); |
2418 } | 2429 } |
2419 } | 2430 } |
2420 | 2431 |
2421 #undef __ | 2432 #undef __ |
2422 | 2433 |
2423 } // namespace compiler | 2434 } // namespace compiler |
2424 } // namespace internal | 2435 } // namespace internal |
2425 } // namespace v8 | 2436 } // namespace v8 |
OLD | NEW |