Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/compiler/ia32/code-generator-ia32.cc

Issue 1702423002: [turbofan] Further fixing ES6 tail call elimination in Turbofan. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@tco-turbo
Patch Set: Addressing comments Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/code-generator.h ('k') | src/compiler/ia32/instruction-selector-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 if (sp_slot_delta < 0) { 348 if (sp_slot_delta < 0) {
349 __ sub(esp, Immediate(-sp_slot_delta * kPointerSize)); 349 __ sub(esp, Immediate(-sp_slot_delta * kPointerSize));
350 frame_access_state()->IncreaseSPDelta(-sp_slot_delta); 350 frame_access_state()->IncreaseSPDelta(-sp_slot_delta);
351 } 351 }
352 if (frame()->needs_frame()) { 352 if (frame()->needs_frame()) {
353 __ mov(ebp, MemOperand(ebp, 0)); 353 __ mov(ebp, MemOperand(ebp, 0));
354 } 354 }
355 frame_access_state()->SetFrameAccessToSP(); 355 frame_access_state()->SetFrameAccessToSP();
356 } 356 }
357 357
358 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
359 Register, Register,
360 Register) {
361 // There are not enough temp registers left on ia32 for a call instruction
362 // so we pick some scratch registers and save/restore them manually here.
363 int scratch_count = 3;
364 Register scratch1 = ebx;
365 Register scratch2 = ecx;
366 Register scratch3 = edx;
367 DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
368 Label done;
369
370 // Check if current frame is an arguments adaptor frame.
371 __ cmp(Operand(ebp, StandardFrameConstants::kContextOffset),
372 Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
373 __ j(not_equal, &done, Label::kNear);
374
375 __ push(scratch1);
376 __ push(scratch2);
377 __ push(scratch3);
378
379 // Load arguments count from current arguments adaptor frame (note, it
380 // does not include receiver).
381 Register caller_args_count_reg = scratch1;
382 __ mov(caller_args_count_reg,
383 Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset));
384 __ SmiUntag(caller_args_count_reg);
385
386 ParameterCount callee_args_count(args_reg);
387 __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
388 scratch3, ReturnAddressState::kOnStack, scratch_count);
389 __ pop(scratch3);
390 __ pop(scratch2);
391 __ pop(scratch1);
392
393 __ bind(&done);
394 }
358 395
359 // Assembles an instruction after register allocation, producing machine code. 396 // Assembles an instruction after register allocation, producing machine code.
360 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { 397 void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
361 IA32OperandConverter i(this, instr); 398 IA32OperandConverter i(this, instr);
362 399 InstructionCode opcode = instr->opcode();
363 switch (ArchOpcodeField::decode(instr->opcode())) { 400 ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode);
401 switch (arch_opcode) {
364 case kArchCallCodeObject: { 402 case kArchCallCodeObject: {
365 EnsureSpaceForLazyDeopt(); 403 EnsureSpaceForLazyDeopt();
366 if (HasImmediateInput(instr, 0)) { 404 if (HasImmediateInput(instr, 0)) {
367 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); 405 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
368 __ call(code, RelocInfo::CODE_TARGET); 406 __ call(code, RelocInfo::CODE_TARGET);
369 } else { 407 } else {
370 Register reg = i.InputRegister(0); 408 Register reg = i.InputRegister(0);
371 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); 409 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag));
372 __ call(reg); 410 __ call(reg);
373 } 411 }
374 RecordCallPosition(instr); 412 RecordCallPosition(instr);
375 frame_access_state()->ClearSPDelta(); 413 frame_access_state()->ClearSPDelta();
376 break; 414 break;
377 } 415 }
416 case kArchTailCallCodeObjectFromJSFunction:
378 case kArchTailCallCodeObject: { 417 case kArchTailCallCodeObject: {
379 int stack_param_delta = i.InputInt32(instr->InputCount() - 1); 418 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
380 AssembleDeconstructActivationRecord(stack_param_delta); 419 AssembleDeconstructActivationRecord(stack_param_delta);
420 if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) {
421 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
422 no_reg, no_reg, no_reg);
423 }
381 if (HasImmediateInput(instr, 0)) { 424 if (HasImmediateInput(instr, 0)) {
382 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); 425 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
383 __ jmp(code, RelocInfo::CODE_TARGET); 426 __ jmp(code, RelocInfo::CODE_TARGET);
384 } else { 427 } else {
385 Register reg = i.InputRegister(0); 428 Register reg = i.InputRegister(0);
386 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); 429 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag));
387 __ jmp(reg); 430 __ jmp(reg);
388 } 431 }
389 frame_access_state()->ClearSPDelta(); 432 frame_access_state()->ClearSPDelta();
390 break; 433 break;
391 } 434 }
392 case kArchCallJSFunction: { 435 case kArchCallJSFunction: {
393 EnsureSpaceForLazyDeopt(); 436 EnsureSpaceForLazyDeopt();
394 Register func = i.InputRegister(0); 437 Register func = i.InputRegister(0);
395 if (FLAG_debug_code) { 438 if (FLAG_debug_code) {
396 // Check the function's context matches the context argument. 439 // Check the function's context matches the context argument.
397 __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset)); 440 __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset));
398 __ Assert(equal, kWrongFunctionContext); 441 __ Assert(equal, kWrongFunctionContext);
399 } 442 }
400 __ call(FieldOperand(func, JSFunction::kCodeEntryOffset)); 443 __ call(FieldOperand(func, JSFunction::kCodeEntryOffset));
401 RecordCallPosition(instr); 444 RecordCallPosition(instr);
402 frame_access_state()->ClearSPDelta(); 445 frame_access_state()->ClearSPDelta();
403 break; 446 break;
404 } 447 }
448 case kArchTailCallJSFunctionFromJSFunction:
405 case kArchTailCallJSFunction: { 449 case kArchTailCallJSFunction: {
406 Register func = i.InputRegister(0); 450 Register func = i.InputRegister(0);
407 if (FLAG_debug_code) { 451 if (FLAG_debug_code) {
408 // Check the function's context matches the context argument. 452 // Check the function's context matches the context argument.
409 __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset)); 453 __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset));
410 __ Assert(equal, kWrongFunctionContext); 454 __ Assert(equal, kWrongFunctionContext);
411 } 455 }
412 int stack_param_delta = i.InputInt32(instr->InputCount() - 1); 456 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
413 AssembleDeconstructActivationRecord(stack_param_delta); 457 AssembleDeconstructActivationRecord(stack_param_delta);
458 if (arch_opcode == kArchTailCallJSFunctionFromJSFunction) {
459 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
460 no_reg, no_reg, no_reg);
461 }
414 __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset)); 462 __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset));
415 frame_access_state()->ClearSPDelta(); 463 frame_access_state()->ClearSPDelta();
416 break; 464 break;
417 } 465 }
418 case kArchPrepareCallCFunction: { 466 case kArchPrepareCallCFunction: {
419 // Frame alignment requires using FP-relative frame addressing. 467 // Frame alignment requires using FP-relative frame addressing.
420 frame_access_state()->SetFrameAccessToFP(); 468 frame_access_state()->SetFrameAccessToFP();
421 int const num_parameters = MiscField::decode(instr->opcode()); 469 int const num_parameters = MiscField::decode(instr->opcode());
422 __ PrepareCallCFunction(num_parameters, i.TempRegister(0)); 470 __ PrepareCallCFunction(num_parameters, i.TempRegister(0));
423 break; 471 break;
(...skipping 1332 matching lines...) Expand 10 before | Expand all | Expand 10 after
1756 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; 1804 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
1757 __ Nop(padding_size); 1805 __ Nop(padding_size);
1758 } 1806 }
1759 } 1807 }
1760 1808
1761 #undef __ 1809 #undef __
1762 1810
1763 } // namespace compiler 1811 } // namespace compiler
1764 } // namespace internal 1812 } // namespace internal
1765 } // namespace v8 1813 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/code-generator.h ('k') | src/compiler/ia32/instruction-selector-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698