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

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

Issue 1777563002: X87: [turbofan] Further fixing ES6 tail call elimination in Turbofan. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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 | « no previous file | src/compiler/x87/instruction-selector-x87.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 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 if (sp_slot_delta < 0) { 355 if (sp_slot_delta < 0) {
356 __ sub(esp, Immediate(-sp_slot_delta * kPointerSize)); 356 __ sub(esp, Immediate(-sp_slot_delta * kPointerSize));
357 frame_access_state()->IncreaseSPDelta(-sp_slot_delta); 357 frame_access_state()->IncreaseSPDelta(-sp_slot_delta);
358 } 358 }
359 if (frame()->needs_frame()) { 359 if (frame()->needs_frame()) {
360 __ mov(ebp, MemOperand(ebp, 0)); 360 __ mov(ebp, MemOperand(ebp, 0));
361 } 361 }
362 frame_access_state()->SetFrameAccessToSP(); 362 frame_access_state()->SetFrameAccessToSP();
363 } 363 }
364 364
365 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
366 Register, Register,
367 Register) {
368 // There are not enough temp registers left on ia32 for a call instruction
369 // so we pick some scratch registers and save/restore them manually here.
370 int scratch_count = 3;
371 Register scratch1 = ebx;
372 Register scratch2 = ecx;
373 Register scratch3 = edx;
374 DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
375 Label done;
376
377 // Check if current frame is an arguments adaptor frame.
378 __ cmp(Operand(ebp, StandardFrameConstants::kContextOffset),
379 Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
380 __ j(not_equal, &done, Label::kNear);
381
382 __ push(scratch1);
383 __ push(scratch2);
384 __ push(scratch3);
385
386 // Load arguments count from current arguments adaptor frame (note, it
387 // does not include receiver).
388 Register caller_args_count_reg = scratch1;
389 __ mov(caller_args_count_reg,
390 Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset));
391 __ SmiUntag(caller_args_count_reg);
392
393 ParameterCount callee_args_count(args_reg);
394 __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
395 scratch3, ReturnAddressState::kOnStack, scratch_count);
396 __ pop(scratch3);
397 __ pop(scratch2);
398 __ pop(scratch1);
399
400 __ bind(&done);
401 }
365 402
366 // Assembles an instruction after register allocation, producing machine code. 403 // Assembles an instruction after register allocation, producing machine code.
367 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { 404 void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
368 X87OperandConverter i(this, instr); 405 X87OperandConverter i(this, instr);
369 406 InstructionCode opcode = instr->opcode();
370 switch (ArchOpcodeField::decode(instr->opcode())) { 407 ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode);
408 switch (arch_opcode) {
371 case kArchCallCodeObject: { 409 case kArchCallCodeObject: {
372 if (FLAG_debug_code && FLAG_enable_slow_asserts) { 410 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
373 __ VerifyX87StackDepth(1); 411 __ VerifyX87StackDepth(1);
374 } 412 }
375 __ fstp(0); 413 __ fstp(0);
376 EnsureSpaceForLazyDeopt(); 414 EnsureSpaceForLazyDeopt();
377 if (HasImmediateInput(instr, 0)) { 415 if (HasImmediateInput(instr, 0)) {
378 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); 416 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
379 __ call(code, RelocInfo::CODE_TARGET); 417 __ call(code, RelocInfo::CODE_TARGET);
380 } else { 418 } else {
(...skipping 11 matching lines...) Expand all
392 __ fninit(); 430 __ fninit();
393 if (double_result) { 431 if (double_result) {
394 __ fld_d(Operand(esp, 0)); 432 __ fld_d(Operand(esp, 0));
395 __ lea(esp, Operand(esp, kDoubleSize)); 433 __ lea(esp, Operand(esp, kDoubleSize));
396 } else { 434 } else {
397 __ fld1(); 435 __ fld1();
398 } 436 }
399 frame_access_state()->ClearSPDelta(); 437 frame_access_state()->ClearSPDelta();
400 break; 438 break;
401 } 439 }
440 case kArchTailCallCodeObjectFromJSFunction:
402 case kArchTailCallCodeObject: { 441 case kArchTailCallCodeObject: {
403 if (FLAG_debug_code && FLAG_enable_slow_asserts) { 442 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
404 __ VerifyX87StackDepth(1); 443 __ VerifyX87StackDepth(1);
405 } 444 }
406 __ fstp(0); 445 __ fstp(0);
407 int stack_param_delta = i.InputInt32(instr->InputCount() - 1); 446 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
408 AssembleDeconstructActivationRecord(stack_param_delta); 447 AssembleDeconstructActivationRecord(stack_param_delta);
448 if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) {
449 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
450 no_reg, no_reg, no_reg);
451 }
409 if (HasImmediateInput(instr, 0)) { 452 if (HasImmediateInput(instr, 0)) {
410 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); 453 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
411 __ jmp(code, RelocInfo::CODE_TARGET); 454 __ jmp(code, RelocInfo::CODE_TARGET);
412 } else { 455 } else {
413 Register reg = i.InputRegister(0); 456 Register reg = i.InputRegister(0);
414 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); 457 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag));
415 __ jmp(reg); 458 __ jmp(reg);
416 } 459 }
417 frame_access_state()->ClearSPDelta(); 460 frame_access_state()->ClearSPDelta();
418 break; 461 break;
(...skipping 21 matching lines...) Expand all
440 __ fninit(); 483 __ fninit();
441 if (double_result) { 484 if (double_result) {
442 __ fld_d(Operand(esp, 0)); 485 __ fld_d(Operand(esp, 0));
443 __ lea(esp, Operand(esp, kDoubleSize)); 486 __ lea(esp, Operand(esp, kDoubleSize));
444 } else { 487 } else {
445 __ fld1(); 488 __ fld1();
446 } 489 }
447 frame_access_state()->ClearSPDelta(); 490 frame_access_state()->ClearSPDelta();
448 break; 491 break;
449 } 492 }
493 case kArchTailCallJSFunctionFromJSFunction:
450 case kArchTailCallJSFunction: { 494 case kArchTailCallJSFunction: {
451 Register func = i.InputRegister(0); 495 Register func = i.InputRegister(0);
452 if (FLAG_debug_code) { 496 if (FLAG_debug_code) {
453 // Check the function's context matches the context argument. 497 // Check the function's context matches the context argument.
454 __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset)); 498 __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset));
455 __ Assert(equal, kWrongFunctionContext); 499 __ Assert(equal, kWrongFunctionContext);
456 } 500 }
457 if (FLAG_debug_code && FLAG_enable_slow_asserts) { 501 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
458 __ VerifyX87StackDepth(1); 502 __ VerifyX87StackDepth(1);
459 } 503 }
460 __ fstp(0); 504 __ fstp(0);
461 int stack_param_delta = i.InputInt32(instr->InputCount() - 1); 505 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
462 AssembleDeconstructActivationRecord(stack_param_delta); 506 AssembleDeconstructActivationRecord(stack_param_delta);
507 if (arch_opcode == kArchTailCallJSFunctionFromJSFunction) {
508 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
509 no_reg, no_reg, no_reg);
510 }
463 __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset)); 511 __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset));
464 frame_access_state()->ClearSPDelta(); 512 frame_access_state()->ClearSPDelta();
465 break; 513 break;
466 } 514 }
467 case kArchPrepareCallCFunction: { 515 case kArchPrepareCallCFunction: {
468 // Frame alignment requires using FP-relative frame addressing. 516 // Frame alignment requires using FP-relative frame addressing.
469 frame_access_state()->SetFrameAccessToFP(); 517 frame_access_state()->SetFrameAccessToFP();
470 int const num_parameters = MiscField::decode(instr->opcode()); 518 int const num_parameters = MiscField::decode(instr->opcode());
471 __ PrepareCallCFunction(num_parameters, i.TempRegister(0)); 519 __ PrepareCallCFunction(num_parameters, i.TempRegister(0));
472 break; 520 break;
(...skipping 1821 matching lines...) Expand 10 before | Expand all | Expand 10 after
2294 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; 2342 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
2295 __ Nop(padding_size); 2343 __ Nop(padding_size);
2296 } 2344 }
2297 } 2345 }
2298 2346
2299 #undef __ 2347 #undef __
2300 2348
2301 } // namespace compiler 2349 } // namespace compiler
2302 } // namespace internal 2350 } // namespace internal
2303 } // namespace v8 2351 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/x87/instruction-selector-x87.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698