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

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: Rebasing 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
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
363 switch (ArchOpcodeField::decode(instr->opcode())) { 400 switch (ArchOpcodeField::decode(instr->opcode())) {
364 case kArchCallCodeObject: { 401 case kArchCallCodeObject: {
365 EnsureSpaceForLazyDeopt(); 402 EnsureSpaceForLazyDeopt();
366 if (HasImmediateInput(instr, 0)) { 403 if (HasImmediateInput(instr, 0)) {
367 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); 404 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
368 __ call(code, RelocInfo::CODE_TARGET); 405 __ call(code, RelocInfo::CODE_TARGET);
369 } else { 406 } else {
370 Register reg = i.InputRegister(0); 407 Register reg = i.InputRegister(0);
371 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); 408 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag));
372 __ call(reg); 409 __ call(reg);
373 } 410 }
374 RecordCallPosition(instr); 411 RecordCallPosition(instr);
375 frame_access_state()->ClearSPDelta(); 412 frame_access_state()->ClearSPDelta();
376 break; 413 break;
377 } 414 }
415 case kArchTailCallCodeObjectFromJSFunction: {
416 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
417 AssembleDeconstructActivationRecord(stack_param_delta);
418 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, no_reg,
419 no_reg, no_reg);
420 if (HasImmediateInput(instr, 0)) {
421 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
422 __ jmp(code, RelocInfo::CODE_TARGET);
423 } else {
424 Register reg = i.InputRegister(0);
425 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag));
426 __ jmp(reg);
427 }
428 frame_access_state()->ClearSPDelta();
429 break;
430 }
378 case kArchTailCallCodeObject: { 431 case kArchTailCallCodeObject: {
379 int stack_param_delta = i.InputInt32(instr->InputCount() - 1); 432 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
380 AssembleDeconstructActivationRecord(stack_param_delta); 433 AssembleDeconstructActivationRecord(stack_param_delta);
381 if (HasImmediateInput(instr, 0)) { 434 if (HasImmediateInput(instr, 0)) {
382 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); 435 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
383 __ jmp(code, RelocInfo::CODE_TARGET); 436 __ jmp(code, RelocInfo::CODE_TARGET);
384 } else { 437 } else {
385 Register reg = i.InputRegister(0); 438 Register reg = i.InputRegister(0);
386 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); 439 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag));
387 __ jmp(reg); 440 __ jmp(reg);
388 } 441 }
389 frame_access_state()->ClearSPDelta(); 442 frame_access_state()->ClearSPDelta();
390 break; 443 break;
391 } 444 }
392 case kArchCallJSFunction: { 445 case kArchCallJSFunction: {
393 EnsureSpaceForLazyDeopt(); 446 EnsureSpaceForLazyDeopt();
394 Register func = i.InputRegister(0); 447 Register func = i.InputRegister(0);
395 if (FLAG_debug_code) { 448 if (FLAG_debug_code) {
396 // Check the function's context matches the context argument. 449 // Check the function's context matches the context argument.
397 __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset)); 450 __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset));
398 __ Assert(equal, kWrongFunctionContext); 451 __ Assert(equal, kWrongFunctionContext);
399 } 452 }
400 __ call(FieldOperand(func, JSFunction::kCodeEntryOffset)); 453 __ call(FieldOperand(func, JSFunction::kCodeEntryOffset));
401 RecordCallPosition(instr); 454 RecordCallPosition(instr);
402 frame_access_state()->ClearSPDelta(); 455 frame_access_state()->ClearSPDelta();
403 break; 456 break;
404 } 457 }
458 case kArchTailCallJSFunctionFromJSFunction: {
459 Register func = i.InputRegister(0);
460 if (FLAG_debug_code) {
461 // Check the function's context matches the context argument.
462 __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset));
463 __ Assert(equal, kWrongFunctionContext);
464 }
465 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
466 AssembleDeconstructActivationRecord(stack_param_delta);
467 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, no_reg,
468 no_reg, no_reg);
469 __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset));
470 frame_access_state()->ClearSPDelta();
471 break;
472 }
405 case kArchTailCallJSFunction: { 473 case kArchTailCallJSFunction: {
406 Register func = i.InputRegister(0); 474 Register func = i.InputRegister(0);
407 if (FLAG_debug_code) { 475 if (FLAG_debug_code) {
408 // Check the function's context matches the context argument. 476 // Check the function's context matches the context argument.
409 __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset)); 477 __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset));
410 __ Assert(equal, kWrongFunctionContext); 478 __ Assert(equal, kWrongFunctionContext);
411 } 479 }
412 int stack_param_delta = i.InputInt32(instr->InputCount() - 1); 480 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
413 AssembleDeconstructActivationRecord(stack_param_delta); 481 AssembleDeconstructActivationRecord(stack_param_delta);
414 __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset)); 482 __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset));
(...skipping 1341 matching lines...) Expand 10 before | Expand all | Expand 10 after
1756 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; 1824 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
1757 __ Nop(padding_size); 1825 __ Nop(padding_size);
1758 } 1826 }
1759 } 1827 }
1760 1828
1761 #undef __ 1829 #undef __
1762 1830
1763 } // namespace compiler 1831 } // namespace compiler
1764 } // namespace internal 1832 } // namespace internal
1765 } // namespace v8 1833 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698