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

Side by Side Diff: src/interpreter/bytecode-generator.cc

Issue 2642843002: Revert of [Ignition/turbo] Add a CallWithSpread bytecode. (Closed)
Patch Set: Created 3 years, 11 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/interpreter/bytecode-array-builder.cc ('k') | src/interpreter/bytecodes.h » ('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 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/interpreter/bytecode-generator.h" 5 #include "src/interpreter/bytecode-generator.h"
6 6
7 #include "src/ast/compile-time-value.h" 7 #include "src/ast/compile-time-value.h"
8 #include "src/ast/scopes.h" 8 #include "src/ast/scopes.h"
9 #include "src/builtins/builtins-constructor.h" 9 #include "src/builtins/builtins-constructor.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 2444 matching lines...) Expand 10 before | Expand all | Expand 10 after
2455 } 2455 }
2456 2456
2457 void BytecodeGenerator::VisitCall(Call* expr) { 2457 void BytecodeGenerator::VisitCall(Call* expr) {
2458 Expression* callee_expr = expr->expression(); 2458 Expression* callee_expr = expr->expression();
2459 Call::CallType call_type = expr->GetCallType(); 2459 Call::CallType call_type = expr->GetCallType();
2460 2460
2461 if (call_type == Call::SUPER_CALL) { 2461 if (call_type == Call::SUPER_CALL) {
2462 return VisitCallSuper(expr); 2462 return VisitCallSuper(expr);
2463 } 2463 }
2464 2464
2465 Register callee = register_allocator()->NewRegister();
2465 // Grow the args list as we visit receiver / arguments to avoid allocating all 2466 // Grow the args list as we visit receiver / arguments to avoid allocating all
2466 // the registers up-front. Otherwise these registers are unavailable during 2467 // the registers up-front. Otherwise these registers are unavailable during
2467 // receiver / argument visiting and we can end up with memory leaks due to 2468 // receiver / argument visiting and we can end up with memory leaks due to
2468 // registers keeping objects alive. 2469 // registers keeping objects alive.
2469 RegisterList args; 2470 RegisterList args = register_allocator()->NewGrowableRegisterList();
2470 Register callee;
2471 // The CallWithSpread bytecode takes all arguments in a register list so that
2472 // it can easily call into a runtime function for its implementation. This
2473 // will change once CallWithSpread has an implementation in ASM.
2474 // TODO(petermarshall): Remove this special path when CallWithSpread is done.
2475 if (expr->only_last_arg_is_spread()) {
2476 args = register_allocator()->NewGrowableRegisterList();
2477 callee = register_allocator()->GrowRegisterList(&args);
2478 } else {
2479 callee = register_allocator()->NewRegister();
2480 args = register_allocator()->NewGrowableRegisterList();
2481 }
2482
2483 // TODO(petermarshall): We have a lot of call bytecodes that are very similar,
2484 // see if we can reduce the number by adding a separate argument which
2485 // specifies the call type (e.g., property, spread, tailcall, etc.).
2486 2471
2487 // Prepare the callee and the receiver to the function call. This depends on 2472 // Prepare the callee and the receiver to the function call. This depends on
2488 // the semantics of the underlying call type. 2473 // the semantics of the underlying call type.
2489 switch (call_type) { 2474 switch (call_type) {
2490 case Call::NAMED_PROPERTY_CALL: 2475 case Call::NAMED_PROPERTY_CALL:
2491 case Call::KEYED_PROPERTY_CALL: { 2476 case Call::KEYED_PROPERTY_CALL: {
2492 Property* property = callee_expr->AsProperty(); 2477 Property* property = callee_expr->AsProperty();
2493 VisitAndPushIntoRegisterList(property->obj(), &args); 2478 VisitAndPushIntoRegisterList(property->obj(), &args);
2494 VisitPropertyLoadForRegister(args.last_register(), property, callee); 2479 VisitPropertyLoadForRegister(args[0], property, callee);
2495 break; 2480 break;
2496 } 2481 }
2497 case Call::GLOBAL_CALL: { 2482 case Call::GLOBAL_CALL: {
2498 // Receiver is undefined for global calls. 2483 // Receiver is undefined for global calls.
2499 BuildPushUndefinedIntoRegisterList(&args); 2484 BuildPushUndefinedIntoRegisterList(&args);
2500 // Load callee as a global variable. 2485 // Load callee as a global variable.
2501 VariableProxy* proxy = callee_expr->AsVariableProxy(); 2486 VariableProxy* proxy = callee_expr->AsVariableProxy();
2502 BuildVariableLoadForAccumulatorValue(proxy->var(), 2487 BuildVariableLoadForAccumulatorValue(proxy->var(),
2503 proxy->VariableFeedbackSlot(), 2488 proxy->VariableFeedbackSlot(),
2504 proxy->hole_check_mode()); 2489 proxy->hole_check_mode());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2545 break; 2530 break;
2546 } 2531 }
2547 case Call::SUPER_CALL: 2532 case Call::SUPER_CALL:
2548 UNREACHABLE(); 2533 UNREACHABLE();
2549 break; 2534 break;
2550 } 2535 }
2551 2536
2552 // Evaluate all arguments to the function call and store in sequential args 2537 // Evaluate all arguments to the function call and store in sequential args
2553 // registers. 2538 // registers.
2554 VisitArguments(expr->arguments(), &args); 2539 VisitArguments(expr->arguments(), &args);
2555 // TODO(petermarshall): Check this for spread calls as well when 2540 CHECK_EQ(expr->arguments()->length() + 1, args.register_count());
2556 // CallWithSpread is done.
2557 if (!expr->only_last_arg_is_spread()) {
2558 CHECK_EQ(expr->arguments()->length() + 1, args.register_count());
2559 }
2560 2541
2561 // Resolve callee for a potential direct eval call. This block will mutate the 2542 // Resolve callee for a potential direct eval call. This block will mutate the
2562 // callee value. 2543 // callee value.
2563 if (expr->is_possibly_eval() && expr->arguments()->length() > 0) { 2544 if (expr->is_possibly_eval() && expr->arguments()->length() > 0) {
2564 RegisterAllocationScope inner_register_scope(this); 2545 RegisterAllocationScope inner_register_scope(this);
2565 // Set up arguments for ResolvePossiblyDirectEval by copying callee, source 2546 // Set up arguments for ResolvePossiblyDirectEval by copying callee, source
2566 // strings and function closure, and loading language and 2547 // strings and function closure, and loading language and
2567 // position. 2548 // position.
2568 RegisterList runtime_call_args = register_allocator()->NewRegisterList(6); 2549 RegisterList runtime_call_args = register_allocator()->NewRegisterList(6);
2569 builder() 2550 builder()
2570 ->MoveRegister(callee, runtime_call_args[0]) 2551 ->MoveRegister(callee, runtime_call_args[0])
2571 .MoveRegister(args[1], runtime_call_args[1]) 2552 .MoveRegister(args[1], runtime_call_args[1])
2572 .MoveRegister(Register::function_closure(), runtime_call_args[2]) 2553 .MoveRegister(Register::function_closure(), runtime_call_args[2])
2573 .LoadLiteral(Smi::FromInt(language_mode())) 2554 .LoadLiteral(Smi::FromInt(language_mode()))
2574 .StoreAccumulatorInRegister(runtime_call_args[3]) 2555 .StoreAccumulatorInRegister(runtime_call_args[3])
2575 .LoadLiteral( 2556 .LoadLiteral(
2576 Smi::FromInt(execution_context()->scope()->start_position())) 2557 Smi::FromInt(execution_context()->scope()->start_position()))
2577 .StoreAccumulatorInRegister(runtime_call_args[4]) 2558 .StoreAccumulatorInRegister(runtime_call_args[4])
2578 .LoadLiteral(Smi::FromInt(expr->position())) 2559 .LoadLiteral(Smi::FromInt(expr->position()))
2579 .StoreAccumulatorInRegister(runtime_call_args[5]); 2560 .StoreAccumulatorInRegister(runtime_call_args[5]);
2580 2561
2581 // Call ResolvePossiblyDirectEval and modify the callee. 2562 // Call ResolvePossiblyDirectEval and modify the callee.
2582 builder() 2563 builder()
2583 ->CallRuntime(Runtime::kResolvePossiblyDirectEval, runtime_call_args) 2564 ->CallRuntime(Runtime::kResolvePossiblyDirectEval, runtime_call_args)
2584 .StoreAccumulatorInRegister(callee); 2565 .StoreAccumulatorInRegister(callee);
2585 } 2566 }
2586 2567
2587 builder()->SetExpressionPosition(expr); 2568 builder()->SetExpressionPosition(expr);
2588 2569
2589 // When a call contains a spread, a Call AST node is only created if there is 2570 int const feedback_slot_index = feedback_index(expr->CallFeedbackICSlot());
2590 // exactly one spread, and it is the last argument. 2571 builder()->Call(callee, args, feedback_slot_index, call_type,
2591 if (expr->only_last_arg_is_spread()) { 2572 expr->tail_call_mode());
2592 CHECK_EQ(expr->arguments()->length() + 2, args.register_count());
2593 DCHECK_EQ(TailCallMode::kDisallow, expr->tail_call_mode());
2594 builder()->CallWithSpread(args);
2595 } else {
2596 int const feedback_slot_index = feedback_index(expr->CallFeedbackICSlot());
2597 builder()->Call(callee, args, feedback_slot_index, call_type,
2598 expr->tail_call_mode());
2599 }
2600 } 2573 }
2601 2574
2602 void BytecodeGenerator::VisitCallSuper(Call* expr) { 2575 void BytecodeGenerator::VisitCallSuper(Call* expr) {
2603 RegisterAllocationScope register_scope(this); 2576 RegisterAllocationScope register_scope(this);
2604 SuperCallReference* super = expr->expression()->AsSuperCallReference(); 2577 SuperCallReference* super = expr->expression()->AsSuperCallReference();
2605 2578
2606 // Prepare the constructor to the super call. 2579 // Prepare the constructor to the super call.
2607 VisitForAccumulatorValue(super->this_function_var()); 2580 VisitForAccumulatorValue(super->this_function_var());
2608 Register constructor = register_allocator()->NewRegister(); 2581 Register constructor = register_allocator()->NewRegister();
2609 builder()->GetSuperConstructor(constructor); 2582 builder()->GetSuperConstructor(constructor);
2610 2583
2611 ZoneList<Expression*>* args = expr->arguments(); 2584 ZoneList<Expression*>* args = expr->arguments();
2612 RegisterList args_regs = register_allocator()->NewGrowableRegisterList(); 2585 RegisterList args_regs = register_allocator()->NewGrowableRegisterList();
2613 VisitArguments(args, &args_regs); 2586 VisitArguments(args, &args_regs);
2614 // The new target is loaded into the accumulator from the 2587 // The new target is loaded into the accumulator from the
2615 // {new.target} variable. 2588 // {new.target} variable.
2616 VisitForAccumulatorValue(super->new_target_var()); 2589 VisitForAccumulatorValue(super->new_target_var());
2617 builder()->SetExpressionPosition(expr); 2590 builder()->SetExpressionPosition(expr);
2618 2591
2619 // When a super call contains a spread, a CallSuper AST node is only created 2592 // When a super call contains a spread, a CallSuper AST node is only created
2620 // if there is exactly one spread, and it is the last argument. 2593 // if there is exactly one spread, and it is the last argument.
2621 if (expr->only_last_arg_is_spread()) { 2594 if (!args->is_empty() && args->last()->IsSpread()) {
2622 // TODO(petermarshall): Collect type on the feedback slot. 2595 // TODO(petermarshall): Collect type on the feedback slot.
2623 builder()->NewWithSpread(constructor, args_regs); 2596 builder()->NewWithSpread(constructor, args_regs);
2624 } else { 2597 } else {
2625 // Call construct. 2598 // Call construct.
2626 // TODO(turbofan): For now we do gather feedback on super constructor 2599 // TODO(turbofan): For now we do gather feedback on super constructor
2627 // calls, utilizing the existing machinery to inline the actual call 2600 // calls, utilizing the existing machinery to inline the actual call
2628 // target and the JSCreate for the implicit receiver allocation. This 2601 // target and the JSCreate for the implicit receiver allocation. This
2629 // is not an ideal solution for super constructor calls, but it gets 2602 // is not an ideal solution for super constructor calls, but it gets
2630 // the job done for now. In the long run we might want to revisit this 2603 // the job done for now. In the long run we might want to revisit this
2631 // and come up with a better way. 2604 // and come up with a better way.
2632 int const feedback_slot_index = feedback_index(expr->CallFeedbackICSlot()); 2605 int const feedback_slot_index = feedback_index(expr->CallFeedbackICSlot());
2633 builder()->New(constructor, args_regs, feedback_slot_index); 2606 builder()->New(constructor, args_regs, feedback_slot_index);
2634 } 2607 }
2635 } 2608 }
2636 2609
2637 void BytecodeGenerator::VisitCallNew(CallNew* expr) { 2610 void BytecodeGenerator::VisitCallNew(CallNew* expr) {
2638 Register constructor = VisitForRegisterValue(expr->expression()); 2611 Register constructor = VisitForRegisterValue(expr->expression());
2639 RegisterList args = register_allocator()->NewGrowableRegisterList(); 2612 RegisterList args = register_allocator()->NewGrowableRegisterList();
2640 VisitArguments(expr->arguments(), &args); 2613 VisitArguments(expr->arguments(), &args);
2641 2614
2615 builder()->SetExpressionPosition(expr);
2642 // The accumulator holds new target which is the same as the 2616 // The accumulator holds new target which is the same as the
2643 // constructor for CallNew. 2617 // constructor for CallNew.
2644 builder()->SetExpressionPosition(expr); 2618 builder()
2645 builder()->LoadAccumulatorWithRegister(constructor); 2619 ->LoadAccumulatorWithRegister(constructor)
2646 2620 .New(constructor, args, feedback_index(expr->CallNewFeedbackSlot()));
2647 if (expr->only_last_arg_is_spread()) {
2648 // TODO(petermarshall): Collect type on the feedback slot.
2649 builder()->NewWithSpread(constructor, args);
2650 } else {
2651 builder()->New(constructor, args,
2652 feedback_index(expr->CallNewFeedbackSlot()));
2653 }
2654 } 2621 }
2655 2622
2656 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { 2623 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) {
2657 if (expr->is_jsruntime()) { 2624 if (expr->is_jsruntime()) {
2658 RegisterList args = register_allocator()->NewGrowableRegisterList(); 2625 RegisterList args = register_allocator()->NewGrowableRegisterList();
2659 // Allocate a register for the receiver and load it with undefined. 2626 // Allocate a register for the receiver and load it with undefined.
2660 BuildPushUndefinedIntoRegisterList(&args); 2627 BuildPushUndefinedIntoRegisterList(&args);
2661 VisitArguments(expr->arguments(), &args); 2628 VisitArguments(expr->arguments(), &args);
2662 builder()->CallJSRuntime(expr->context_index(), args); 2629 builder()->CallJSRuntime(expr->context_index(), args);
2663 } else { 2630 } else {
(...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after
3391 } 3358 }
3392 3359
3393 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { 3360 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() {
3394 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict 3361 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict
3395 : Runtime::kStoreKeyedToSuper_Sloppy; 3362 : Runtime::kStoreKeyedToSuper_Sloppy;
3396 } 3363 }
3397 3364
3398 } // namespace interpreter 3365 } // namespace interpreter
3399 } // namespace internal 3366 } // namespace internal
3400 } // namespace v8 3367 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-array-builder.cc ('k') | src/interpreter/bytecodes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698