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

Side by Side Diff: src/interpreter/interpreter-assembler.cc

Issue 1973873004: [Interpreter] Make Fast-paths of StackCheck, Jump Return, ForInNext not build a frame. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 4 years, 7 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/interpreter-assembler.h ('k') | no next file » | 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/interpreter-assembler.h" 5 #include "src/interpreter/interpreter-assembler.h"
6 6
7 #include <limits> 7 #include <limits>
8 #include <ostream> 8 #include <ostream>
9 9
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 Node* function = IntPtrAdd(function_table, function_offset); 453 Node* function = IntPtrAdd(function_table, function_offset);
454 Node* function_entry = 454 Node* function_entry =
455 Load(MachineType::Pointer(), function, 455 Load(MachineType::Pointer(), function,
456 IntPtrConstant(offsetof(Runtime::Function, entry))); 456 IntPtrConstant(offsetof(Runtime::Function, entry)));
457 457
458 return CallStub(callable.descriptor(), code_target, context, arg_count, 458 return CallStub(callable.descriptor(), code_target, context, arg_count,
459 first_arg, function_entry, result_size); 459 first_arg, function_entry, result_size);
460 } 460 }
461 461
462 void InterpreterAssembler::UpdateInterruptBudget(Node* weight) { 462 void InterpreterAssembler::UpdateInterruptBudget(Node* weight) {
463 CodeStubAssembler::Label ok(this); 463 Label ok(this), interrupt_check(this, Label::kDeferred), end(this);
464 CodeStubAssembler::Label interrupt_check(this);
465 CodeStubAssembler::Label end(this);
466 Node* budget_offset = 464 Node* budget_offset =
467 IntPtrConstant(BytecodeArray::kInterruptBudgetOffset - kHeapObjectTag); 465 IntPtrConstant(BytecodeArray::kInterruptBudgetOffset - kHeapObjectTag);
468 466
469 // Update budget by |weight| and check if it reaches zero. 467 // Update budget by |weight| and check if it reaches zero.
468 Variable new_budget(this, MachineRepresentation::kWord32);
470 Node* old_budget = 469 Node* old_budget =
471 Load(MachineType::Int32(), BytecodeArrayTaggedPointer(), budget_offset); 470 Load(MachineType::Int32(), BytecodeArrayTaggedPointer(), budget_offset);
472 Node* new_budget = Int32Add(old_budget, weight); 471 new_budget.Bind(Int32Add(old_budget, weight));
473 Node* condition = Int32GreaterThanOrEqual(new_budget, Int32Constant(0)); 472 Node* condition =
473 Int32GreaterThanOrEqual(new_budget.value(), Int32Constant(0));
474 Branch(condition, &ok, &interrupt_check); 474 Branch(condition, &ok, &interrupt_check);
475 475
476 // Perform interrupt and reset budget. 476 // Perform interrupt and reset budget.
477 Bind(&interrupt_check); 477 Bind(&interrupt_check);
478 CallRuntime(Runtime::kInterrupt, GetContext()); 478 {
479 StoreNoWriteBarrier(MachineRepresentation::kWord32, 479 CallRuntime(Runtime::kInterrupt, GetContext());
480 BytecodeArrayTaggedPointer(), budget_offset, 480 new_budget.Bind(Int32Constant(Interpreter::InterruptBudget()));
481 Int32Constant(Interpreter::InterruptBudget())); 481 Goto(&ok);
482 Goto(&end); 482 }
483 483
484 // Update budget. 484 // Update budget.
485 Bind(&ok); 485 Bind(&ok);
486 StoreNoWriteBarrier(MachineRepresentation::kWord32, 486 StoreNoWriteBarrier(MachineRepresentation::kWord32,
487 BytecodeArrayTaggedPointer(), budget_offset, new_budget); 487 BytecodeArrayTaggedPointer(), budget_offset,
488 Goto(&end); 488 new_budget.value());
489 Bind(&end);
490 } 489 }
491 490
492 Node* InterpreterAssembler::Advance(int delta) { 491 Node* InterpreterAssembler::Advance(int delta) {
493 return IntPtrAdd(BytecodeOffset(), IntPtrConstant(delta)); 492 return IntPtrAdd(BytecodeOffset(), IntPtrConstant(delta));
494 } 493 }
495 494
496 Node* InterpreterAssembler::Advance(Node* delta) { 495 Node* InterpreterAssembler::Advance(Node* delta) {
497 return IntPtrAdd(BytecodeOffset(), delta); 496 return IntPtrAdd(BytecodeOffset(), delta);
498 } 497 }
499 498
500 Node* InterpreterAssembler::Jump(Node* delta) { 499 Node* InterpreterAssembler::Jump(Node* delta) {
501 UpdateInterruptBudget(delta); 500 UpdateInterruptBudget(delta);
502 return DispatchTo(Advance(delta)); 501 return DispatchTo(Advance(delta));
503 } 502 }
504 503
505 void InterpreterAssembler::JumpConditional(Node* condition, Node* delta) { 504 void InterpreterAssembler::JumpConditional(Node* condition, Node* delta) {
506 CodeStubAssembler::Label match(this); 505 Label match(this), no_match(this);
507 CodeStubAssembler::Label no_match(this);
508 506
509 Branch(condition, &match, &no_match); 507 BranchIf(condition, &match, &no_match);
510 Bind(&match); 508 Bind(&match);
511 Jump(delta); 509 Jump(delta);
512 Bind(&no_match); 510 Bind(&no_match);
513 Dispatch(); 511 Dispatch();
514 } 512 }
515 513
516 void InterpreterAssembler::JumpIfWordEqual(Node* lhs, Node* rhs, Node* delta) { 514 void InterpreterAssembler::JumpIfWordEqual(Node* lhs, Node* rhs, Node* delta) {
517 JumpConditional(WordEqual(lhs, rhs), delta); 515 JumpConditional(WordEqual(lhs, rhs), delta);
518 } 516 }
519 517
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 Node* profiling_weight = 609 Node* profiling_weight =
612 Int32Sub(Int32Constant(kHeapObjectTag + BytecodeArray::kHeaderSize), 610 Int32Sub(Int32Constant(kHeapObjectTag + BytecodeArray::kHeaderSize),
613 BytecodeOffset()); 611 BytecodeOffset());
614 UpdateInterruptBudget(profiling_weight); 612 UpdateInterruptBudget(profiling_weight);
615 613
616 Node* exit_trampoline_code_object = 614 Node* exit_trampoline_code_object =
617 HeapConstant(isolate()->builtins()->InterpreterExitTrampoline()); 615 HeapConstant(isolate()->builtins()->InterpreterExitTrampoline());
618 return DispatchToBytecodeHandler(exit_trampoline_code_object); 616 return DispatchToBytecodeHandler(exit_trampoline_code_object);
619 } 617 }
620 618
621 void InterpreterAssembler::StackCheck() { 619 Node* InterpreterAssembler::StackCheckTriggeredInterrupt() {
622 CodeStubAssembler::Label end(this);
623 CodeStubAssembler::Label ok(this);
624 CodeStubAssembler::Label stack_guard(this);
625
626 Node* sp = LoadStackPointer(); 620 Node* sp = LoadStackPointer();
627 Node* stack_limit = Load( 621 Node* stack_limit = Load(
628 MachineType::Pointer(), 622 MachineType::Pointer(),
629 ExternalConstant(ExternalReference::address_of_stack_limit(isolate()))); 623 ExternalConstant(ExternalReference::address_of_stack_limit(isolate())));
630 Node* condition = UintPtrGreaterThanOrEqual(sp, stack_limit); 624 return UintPtrLessThan(sp, stack_limit);
631 Branch(condition, &ok, &stack_guard);
632 Bind(&stack_guard);
633 CallRuntime(Runtime::kStackGuard, GetContext());
634 Goto(&end);
635 Bind(&ok);
636 Goto(&end);
637 Bind(&end);
638 } 625 }
639 626
640 void InterpreterAssembler::Abort(BailoutReason bailout_reason) { 627 void InterpreterAssembler::Abort(BailoutReason bailout_reason) {
641 disable_stack_check_across_call_ = true; 628 disable_stack_check_across_call_ = true;
642 Node* abort_id = SmiTag(Int32Constant(bailout_reason)); 629 Node* abort_id = SmiTag(Int32Constant(bailout_reason));
643 CallRuntime(Runtime::kAbort, GetContext(), abort_id); 630 CallRuntime(Runtime::kAbort, GetContext(), abort_id);
644 disable_stack_check_across_call_ = false; 631 disable_stack_check_across_call_ = false;
645 } 632 }
646 633
647 void InterpreterAssembler::AbortIfWordNotEqual(Node* lhs, Node* rhs, 634 void InterpreterAssembler::AbortIfWordNotEqual(Node* lhs, Node* rhs,
648 BailoutReason bailout_reason) { 635 BailoutReason bailout_reason) {
649 CodeStubAssembler::Label match(this); 636 Label ok(this), abort(this, Label::kDeferred);
650 CodeStubAssembler::Label no_match(this); 637 BranchIfWordEqual(lhs, rhs, &ok, &abort);
651 CodeStubAssembler::Label end(this);
652 638
653 Node* condition = WordEqual(lhs, rhs); 639 Bind(&abort);
654 Branch(condition, &match, &no_match);
655 Bind(&no_match);
656 Abort(bailout_reason); 640 Abort(bailout_reason);
657 Goto(&end); 641 Goto(&ok);
658 Bind(&match); 642
659 Goto(&end); 643 Bind(&ok);
660 Bind(&end);
661 } 644 }
662 645
663 void InterpreterAssembler::TraceBytecode(Runtime::FunctionId function_id) { 646 void InterpreterAssembler::TraceBytecode(Runtime::FunctionId function_id) {
664 CallRuntime(function_id, GetContext(), BytecodeArrayTaggedPointer(), 647 CallRuntime(function_id, GetContext(), BytecodeArrayTaggedPointer(),
665 SmiTag(BytecodeOffset()), GetAccumulatorUnchecked()); 648 SmiTag(BytecodeOffset()), GetAccumulatorUnchecked());
666 } 649 }
667 650
668 void InterpreterAssembler::TraceBytecodeDispatch(Node* target_bytecode) { 651 void InterpreterAssembler::TraceBytecodeDispatch(Node* target_bytecode) {
669 Node* counters_table = ExternalConstant( 652 Node* counters_table = ExternalConstant(
670 ExternalReference::interpreter_dispatch_counters(isolate())); 653 ExternalReference::interpreter_dispatch_counters(isolate()));
671 Node* source_bytecode_table_index = IntPtrConstant( 654 Node* source_bytecode_table_index = IntPtrConstant(
672 static_cast<int>(bytecode_) * (static_cast<int>(Bytecode::kLast) + 1)); 655 static_cast<int>(bytecode_) * (static_cast<int>(Bytecode::kLast) + 1));
673 656
674 Node* counter_offset = 657 Node* counter_offset =
675 WordShl(IntPtrAdd(source_bytecode_table_index, target_bytecode), 658 WordShl(IntPtrAdd(source_bytecode_table_index, target_bytecode),
676 IntPtrConstant(kPointerSizeLog2)); 659 IntPtrConstant(kPointerSizeLog2));
677 Node* old_counter = 660 Node* old_counter =
678 Load(MachineType::IntPtr(), counters_table, counter_offset); 661 Load(MachineType::IntPtr(), counters_table, counter_offset);
679 662
680 CodeStubAssembler::Label counter_ok(this); 663 Label counter_ok(this), counter_saturated(this, Label::kDeferred);
681 CodeStubAssembler::Label counter_saturated(this);
682 CodeStubAssembler::Label end(this);
683 664
684 Node* counter_reached_max = WordEqual( 665 Node* counter_reached_max = WordEqual(
685 old_counter, IntPtrConstant(std::numeric_limits<uintptr_t>::max())); 666 old_counter, IntPtrConstant(std::numeric_limits<uintptr_t>::max()));
686 Branch(counter_reached_max, &counter_saturated, &counter_ok); 667 BranchIf(counter_reached_max, &counter_saturated, &counter_ok);
668
687 Bind(&counter_ok); 669 Bind(&counter_ok);
688 Node* new_counter = IntPtrAdd(old_counter, IntPtrConstant(1)); 670 {
689 StoreNoWriteBarrier(MachineType::PointerRepresentation(), counters_table, 671 Node* new_counter = IntPtrAdd(old_counter, IntPtrConstant(1));
690 counter_offset, new_counter); 672 StoreNoWriteBarrier(MachineType::PointerRepresentation(), counters_table,
691 Goto(&end); 673 counter_offset, new_counter);
674 Goto(&counter_saturated);
675 }
676
692 Bind(&counter_saturated); 677 Bind(&counter_saturated);
693 Goto(&end);
694 Bind(&end);
695 } 678 }
696 679
697 // static 680 // static
698 bool InterpreterAssembler::TargetSupportsUnalignedAccess() { 681 bool InterpreterAssembler::TargetSupportsUnalignedAccess() {
699 #if V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 682 #if V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
700 return false; 683 return false;
701 #elif V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_PPC 684 #elif V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_PPC
702 return CpuFeatures::IsSupported(UNALIGNED_ACCESSES); 685 return CpuFeatures::IsSupported(UNALIGNED_ACCESSES);
703 #elif V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_X87 || \ 686 #elif V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_X87 || \
704 V8_TARGET_ARCH_S390 687 V8_TARGET_ARCH_S390
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 Goto(&loop); 765 Goto(&loop);
783 } 766 }
784 Bind(&done_loop); 767 Bind(&done_loop);
785 768
786 return array; 769 return array;
787 } 770 }
788 771
789 } // namespace interpreter 772 } // namespace interpreter
790 } // namespace internal 773 } // namespace internal
791 } // namespace v8 774 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/interpreter-assembler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698