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

Side by Side Diff: src/arm64/lithium-codegen-arm64.cc

Issue 582743002: Emit comment with instruction+reason before deopt calls. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased Created 6 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « src/arm64/lithium-codegen-arm64.h ('k') | src/deoptimizer.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 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/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/arm64/lithium-codegen-arm64.h" 7 #include "src/arm64/lithium-codegen-arm64.h"
8 #include "src/arm64/lithium-gap-resolver-arm64.h" 8 #include "src/arm64/lithium-gap-resolver-arm64.h"
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 bool LCodeGen::GenerateCode() { 586 bool LCodeGen::GenerateCode() {
587 LPhase phase("Z_Code generation", chunk()); 587 LPhase phase("Z_Code generation", chunk());
588 DCHECK(is_unused()); 588 DCHECK(is_unused());
589 status_ = GENERATING; 589 status_ = GENERATING;
590 590
591 // Open a frame scope to indicate that there is a frame on the stack. The 591 // Open a frame scope to indicate that there is a frame on the stack. The
592 // NONE indicates that the scope shouldn't actually generate code to set up 592 // NONE indicates that the scope shouldn't actually generate code to set up
593 // the frame (that is done in GeneratePrologue). 593 // the frame (that is done in GeneratePrologue).
594 FrameScope frame_scope(masm_, StackFrame::NONE); 594 FrameScope frame_scope(masm_, StackFrame::NONE);
595 595
596 return GeneratePrologue() && 596 return GeneratePrologue() && GenerateBody() && GenerateDeferredCode() &&
597 GenerateBody() && 597 GenerateJumpTable() && GenerateSafepointTable();
598 GenerateDeferredCode() &&
599 GenerateDeoptJumpTable() &&
600 GenerateSafepointTable();
601 } 598 }
602 599
603 600
604 void LCodeGen::SaveCallerDoubles() { 601 void LCodeGen::SaveCallerDoubles() {
605 DCHECK(info()->saves_caller_doubles()); 602 DCHECK(info()->saves_caller_doubles());
606 DCHECK(NeedsEagerFrame()); 603 DCHECK(NeedsEagerFrame());
607 Comment(";;; Save clobbered callee double registers"); 604 Comment(";;; Save clobbered callee double registers");
608 BitVector* doubles = chunk()->allocated_double_registers(); 605 BitVector* doubles = chunk()->allocated_double_registers();
609 BitVector::Iterator iterator(doubles); 606 BitVector::Iterator iterator(doubles);
610 int count = 0; 607 int count = 0;
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 // Force constant pool emission at the end of the deferred code to make 817 // Force constant pool emission at the end of the deferred code to make
821 // sure that no constant pools are emitted after deferred code because 818 // sure that no constant pools are emitted after deferred code because
822 // deferred code generation is the last step which generates code. The two 819 // deferred code generation is the last step which generates code. The two
823 // following steps will only output data used by crakshaft. 820 // following steps will only output data used by crakshaft.
824 masm()->CheckConstPool(true, false); 821 masm()->CheckConstPool(true, false);
825 822
826 return !is_aborted(); 823 return !is_aborted();
827 } 824 }
828 825
829 826
830 bool LCodeGen::GenerateDeoptJumpTable() { 827 bool LCodeGen::GenerateJumpTable() {
831 Label needs_frame, restore_caller_doubles, call_deopt_entry; 828 Label needs_frame, restore_caller_doubles, call_deopt_entry;
832 829
833 if (deopt_jump_table_.length() > 0) { 830 if (jump_table_.length() > 0) {
834 Comment(";;; -------------------- Jump table --------------------"); 831 Comment(";;; -------------------- Jump table --------------------");
835 Address base = deopt_jump_table_[0]->address; 832 Address base = jump_table_[0]->address;
836 833
837 UseScratchRegisterScope temps(masm()); 834 UseScratchRegisterScope temps(masm());
838 Register entry_offset = temps.AcquireX(); 835 Register entry_offset = temps.AcquireX();
839 836
840 int length = deopt_jump_table_.length(); 837 int length = jump_table_.length();
841 for (int i = 0; i < length; i++) { 838 for (int i = 0; i < length; i++) {
842 __ Bind(&deopt_jump_table_[i]->label); 839 Deoptimizer::JumpTableEntry* table_entry = jump_table_[i];
840 __ Bind(&table_entry->label);
843 841
844 Deoptimizer::BailoutType type = deopt_jump_table_[i]->bailout_type; 842 Deoptimizer::BailoutType type = table_entry->bailout_type;
845 Address entry = deopt_jump_table_[i]->address; 843 Address entry = table_entry->address;
846 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type); 844 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type);
847 if (id == Deoptimizer::kNotDeoptimizationEntry) { 845 if (id == Deoptimizer::kNotDeoptimizationEntry) {
848 Comment(";;; jump table entry %d.", i); 846 Comment(";;; jump table entry %d.", i);
849 } else { 847 } else {
850 Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id); 848 Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id);
851 } 849 }
850 DeoptComment(table_entry->mnemonic, table_entry->reason);
852 851
853 // Second-level deopt table entries are contiguous and small, so instead 852 // Second-level deopt table entries are contiguous and small, so instead
854 // of loading the full, absolute address of each one, load the base 853 // of loading the full, absolute address of each one, load the base
855 // address and add an immediate offset. 854 // address and add an immediate offset.
856 __ Mov(entry_offset, entry - base); 855 __ Mov(entry_offset, entry - base);
857 856
858 // The last entry can fall through into `call_deopt_entry`, avoiding a 857 // The last entry can fall through into `call_deopt_entry`, avoiding a
859 // branch. 858 // branch.
860 bool last_entry = (i + 1) == length; 859 bool last_entry = (i + 1) == length;
861 860
862 if (deopt_jump_table_[i]->needs_frame) { 861 if (table_entry->needs_frame) {
863 DCHECK(!info()->saves_caller_doubles()); 862 DCHECK(!info()->saves_caller_doubles());
864 if (!needs_frame.is_bound()) { 863 if (!needs_frame.is_bound()) {
865 // This variant of deopt can only be used with stubs. Since we don't 864 // This variant of deopt can only be used with stubs. Since we don't
866 // have a function pointer to install in the stack frame that we're 865 // have a function pointer to install in the stack frame that we're
867 // building, install a special marker there instead. 866 // building, install a special marker there instead.
868 DCHECK(info()->IsStub()); 867 DCHECK(info()->IsStub());
869 868
870 UseScratchRegisterScope temps(masm()); 869 UseScratchRegisterScope temps(masm());
871 Register stub_marker = temps.AcquireX(); 870 Register stub_marker = temps.AcquireX();
872 __ Bind(&needs_frame); 871 __ Bind(&needs_frame);
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
990 989
991 for (int i = 0, length = inlined_closures->length(); i < length; i++) { 990 for (int i = 0, length = inlined_closures->length(); i < length; i++) {
992 DefineDeoptimizationLiteral(inlined_closures->at(i)); 991 DefineDeoptimizationLiteral(inlined_closures->at(i));
993 } 992 }
994 993
995 inlined_function_count_ = deoptimization_literals_.length(); 994 inlined_function_count_ = deoptimization_literals_.length();
996 } 995 }
997 996
998 997
999 void LCodeGen::DeoptimizeBranch( 998 void LCodeGen::DeoptimizeBranch(
1000 LInstruction* instr, BranchType branch_type, Register reg, int bit, 999 LInstruction* instr, const char* reason, BranchType branch_type,
1001 Deoptimizer::BailoutType* override_bailout_type) { 1000 Register reg, int bit, Deoptimizer::BailoutType* override_bailout_type) {
1002 LEnvironment* environment = instr->environment(); 1001 LEnvironment* environment = instr->environment();
1003 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); 1002 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
1004 Deoptimizer::BailoutType bailout_type = 1003 Deoptimizer::BailoutType bailout_type =
1005 info()->IsStub() ? Deoptimizer::LAZY : Deoptimizer::EAGER; 1004 info()->IsStub() ? Deoptimizer::LAZY : Deoptimizer::EAGER;
1006 1005
1007 if (override_bailout_type != NULL) { 1006 if (override_bailout_type != NULL) {
1008 bailout_type = *override_bailout_type; 1007 bailout_type = *override_bailout_type;
1009 } 1008 }
1010 1009
1011 DCHECK(environment->HasBeenRegistered()); 1010 DCHECK(environment->HasBeenRegistered());
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1045 Label dont_trap; 1044 Label dont_trap;
1046 __ B(&dont_trap, InvertBranchType(branch_type), reg, bit); 1045 __ B(&dont_trap, InvertBranchType(branch_type), reg, bit);
1047 __ Debug("trap_on_deopt", __LINE__, BREAK); 1046 __ Debug("trap_on_deopt", __LINE__, BREAK);
1048 __ Bind(&dont_trap); 1047 __ Bind(&dont_trap);
1049 } 1048 }
1050 1049
1051 DCHECK(info()->IsStub() || frame_is_built_); 1050 DCHECK(info()->IsStub() || frame_is_built_);
1052 // Go through jump table if we need to build frame, or restore caller doubles. 1051 // Go through jump table if we need to build frame, or restore caller doubles.
1053 if (branch_type == always && 1052 if (branch_type == always &&
1054 frame_is_built_ && !info()->saves_caller_doubles()) { 1053 frame_is_built_ && !info()->saves_caller_doubles()) {
1054 DeoptComment(instr->Mnemonic(), reason);
1055 __ Call(entry, RelocInfo::RUNTIME_ENTRY); 1055 __ Call(entry, RelocInfo::RUNTIME_ENTRY);
1056 } else { 1056 } else {
1057 // We often have several deopts to the same entry, reuse the last 1057 // We often have several deopts to the same entry, reuse the last
1058 // jump entry if this is the case. 1058 // jump entry if this is the case.
1059 if (deopt_jump_table_.is_empty() || 1059 if (jump_table_.is_empty() || (jump_table_.last()->address != entry) ||
1060 (deopt_jump_table_.last()->address != entry) || 1060 (jump_table_.last()->bailout_type != bailout_type) ||
1061 (deopt_jump_table_.last()->bailout_type != bailout_type) || 1061 (jump_table_.last()->needs_frame != !frame_is_built_)) {
1062 (deopt_jump_table_.last()->needs_frame != !frame_is_built_)) {
1063 Deoptimizer::JumpTableEntry* table_entry = 1062 Deoptimizer::JumpTableEntry* table_entry =
1064 new(zone()) Deoptimizer::JumpTableEntry(entry, 1063 new (zone()) Deoptimizer::JumpTableEntry(
1065 bailout_type, 1064 entry, instr->Mnemonic(), reason, bailout_type, !frame_is_built_);
1066 !frame_is_built_); 1065 jump_table_.Add(table_entry, zone());
1067 deopt_jump_table_.Add(table_entry, zone());
1068 } 1066 }
1069 __ B(&deopt_jump_table_.last()->label, 1067 __ B(&jump_table_.last()->label, branch_type, reg, bit);
1070 branch_type, reg, bit);
1071 } 1068 }
1072 } 1069 }
1073 1070
1074 1071
1075 void LCodeGen::Deoptimize(LInstruction* instr, 1072 void LCodeGen::Deoptimize(LInstruction* instr,
1076 Deoptimizer::BailoutType* override_bailout_type) { 1073 Deoptimizer::BailoutType* override_bailout_type,
1077 DeoptimizeBranch(instr, always, NoReg, -1, override_bailout_type); 1074 const char* reason) {
1075 DeoptimizeBranch(instr, reason, always, NoReg, -1, override_bailout_type);
1078 } 1076 }
1079 1077
1080 1078
1081 void LCodeGen::DeoptimizeIf(Condition cond, LInstruction* instr) { 1079 void LCodeGen::DeoptimizeIf(Condition cond, LInstruction* instr,
1082 DeoptimizeBranch(instr, static_cast<BranchType>(cond)); 1080 const char* reason) {
1081 DeoptimizeBranch(instr, reason, static_cast<BranchType>(cond));
1083 } 1082 }
1084 1083
1085 1084
1086 void LCodeGen::DeoptimizeIfZero(Register rt, LInstruction* instr) { 1085 void LCodeGen::DeoptimizeIfZero(Register rt, LInstruction* instr,
1087 DeoptimizeBranch(instr, reg_zero, rt); 1086 const char* reason) {
1087 DeoptimizeBranch(instr, reason, reg_zero, rt);
1088 } 1088 }
1089 1089
1090 1090
1091 void LCodeGen::DeoptimizeIfNotZero(Register rt, LInstruction* instr) { 1091 void LCodeGen::DeoptimizeIfNotZero(Register rt, LInstruction* instr,
1092 DeoptimizeBranch(instr, reg_not_zero, rt); 1092 const char* reason) {
1093 DeoptimizeBranch(instr, reason, reg_not_zero, rt);
1093 } 1094 }
1094 1095
1095 1096
1096 void LCodeGen::DeoptimizeIfNegative(Register rt, LInstruction* instr) { 1097 void LCodeGen::DeoptimizeIfNegative(Register rt, LInstruction* instr,
1098 const char* reason) {
1097 int sign_bit = rt.Is64Bits() ? kXSignBit : kWSignBit; 1099 int sign_bit = rt.Is64Bits() ? kXSignBit : kWSignBit;
1098 DeoptimizeIfBitSet(rt, sign_bit, instr); 1100 DeoptimizeIfBitSet(rt, sign_bit, instr, reason);
1099 } 1101 }
1100 1102
1101 1103
1102 void LCodeGen::DeoptimizeIfSmi(Register rt, LInstruction* instr) { 1104 void LCodeGen::DeoptimizeIfSmi(Register rt, LInstruction* instr,
1103 DeoptimizeIfBitClear(rt, MaskToBit(kSmiTagMask), instr); 1105 const char* reason) {
1106 DeoptimizeIfBitClear(rt, MaskToBit(kSmiTagMask), instr, reason);
1104 } 1107 }
1105 1108
1106 1109
1107 void LCodeGen::DeoptimizeIfNotSmi(Register rt, LInstruction* instr) { 1110 void LCodeGen::DeoptimizeIfNotSmi(Register rt, LInstruction* instr,
1108 DeoptimizeIfBitSet(rt, MaskToBit(kSmiTagMask), instr); 1111 const char* reason) {
1112 DeoptimizeIfBitSet(rt, MaskToBit(kSmiTagMask), instr, reason);
1109 } 1113 }
1110 1114
1111 1115
1112 void LCodeGen::DeoptimizeIfRoot(Register rt, Heap::RootListIndex index, 1116 void LCodeGen::DeoptimizeIfRoot(Register rt, Heap::RootListIndex index,
1113 LInstruction* instr) { 1117 LInstruction* instr, const char* reason) {
1114 __ CompareRoot(rt, index); 1118 __ CompareRoot(rt, index);
1115 DeoptimizeIf(eq, instr); 1119 DeoptimizeIf(eq, instr, reason);
1116 } 1120 }
1117 1121
1118 1122
1119 void LCodeGen::DeoptimizeIfNotRoot(Register rt, Heap::RootListIndex index, 1123 void LCodeGen::DeoptimizeIfNotRoot(Register rt, Heap::RootListIndex index,
1120 LInstruction* instr) { 1124 LInstruction* instr, const char* reason) {
1121 __ CompareRoot(rt, index); 1125 __ CompareRoot(rt, index);
1122 DeoptimizeIf(ne, instr); 1126 DeoptimizeIf(ne, instr, reason);
1123 } 1127 }
1124 1128
1125 1129
1126 void LCodeGen::DeoptimizeIfMinusZero(DoubleRegister input, 1130 void LCodeGen::DeoptimizeIfMinusZero(DoubleRegister input, LInstruction* instr,
1127 LInstruction* instr) { 1131 const char* reason) {
1128 __ TestForMinusZero(input); 1132 __ TestForMinusZero(input);
1129 DeoptimizeIf(vs, instr); 1133 DeoptimizeIf(vs, instr, reason);
1130 } 1134 }
1131 1135
1132 1136
1133 void LCodeGen::DeoptimizeIfBitSet(Register rt, int bit, LInstruction* instr) { 1137 void LCodeGen::DeoptimizeIfBitSet(Register rt, int bit, LInstruction* instr,
1134 DeoptimizeBranch(instr, reg_bit_set, rt, bit); 1138 const char* reason) {
1139 DeoptimizeBranch(instr, reason, reg_bit_set, rt, bit);
1135 } 1140 }
1136 1141
1137 1142
1138 void LCodeGen::DeoptimizeIfBitClear(Register rt, int bit, LInstruction* instr) { 1143 void LCodeGen::DeoptimizeIfBitClear(Register rt, int bit, LInstruction* instr,
1139 DeoptimizeBranch(instr, reg_bit_clear, rt, bit); 1144 const char* reason) {
1145 DeoptimizeBranch(instr, reason, reg_bit_clear, rt, bit);
1140 } 1146 }
1141 1147
1142 1148
1143 void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) { 1149 void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) {
1144 if (!info()->IsStub()) { 1150 if (!info()->IsStub()) {
1145 // Ensure that we have enough space after the previous lazy-bailout 1151 // Ensure that we have enough space after the previous lazy-bailout
1146 // instruction for patching the code here. 1152 // instruction for patching the code here.
1147 intptr_t current_pc = masm()->pc_offset(); 1153 intptr_t current_pc = masm()->pc_offset();
1148 1154
1149 if (current_pc < (last_lazy_deopt_pc_ + space_needed)) { 1155 if (current_pc < (last_lazy_deopt_pc_ + space_needed)) {
(...skipping 1528 matching lines...) Expand 10 before | Expand all | Expand 10 after
2678 void LCodeGen::DoDeoptimize(LDeoptimize* instr) { 2684 void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
2679 Deoptimizer::BailoutType type = instr->hydrogen()->type(); 2685 Deoptimizer::BailoutType type = instr->hydrogen()->type();
2680 // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the 2686 // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the
2681 // needed return address), even though the implementation of LAZY and EAGER is 2687 // needed return address), even though the implementation of LAZY and EAGER is
2682 // now identical. When LAZY is eventually completely folded into EAGER, remove 2688 // now identical. When LAZY is eventually completely folded into EAGER, remove
2683 // the special case below. 2689 // the special case below.
2684 if (info()->IsStub() && (type == Deoptimizer::EAGER)) { 2690 if (info()->IsStub() && (type == Deoptimizer::EAGER)) {
2685 type = Deoptimizer::LAZY; 2691 type = Deoptimizer::LAZY;
2686 } 2692 }
2687 2693
2688 Comment(";;; deoptimize: %s", instr->hydrogen()->reason()); 2694 Deoptimize(instr, &type, instr->hydrogen()->reason());
2689 Deoptimize(instr, &type);
2690 } 2695 }
2691 2696
2692 2697
2693 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { 2698 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
2694 Register dividend = ToRegister32(instr->dividend()); 2699 Register dividend = ToRegister32(instr->dividend());
2695 int32_t divisor = instr->divisor(); 2700 int32_t divisor = instr->divisor();
2696 Register result = ToRegister32(instr->result()); 2701 Register result = ToRegister32(instr->result());
2697 DCHECK(divisor == kMinInt || base::bits::IsPowerOfTwo32(Abs(divisor))); 2702 DCHECK(divisor == kMinInt || base::bits::IsPowerOfTwo32(Abs(divisor)));
2698 DCHECK(!result.is(dividend)); 2703 DCHECK(!result.is(dividend));
2699 2704
(...skipping 3335 matching lines...) Expand 10 before | Expand all | Expand 10 after
6035 Handle<ScopeInfo> scope_info = instr->scope_info(); 6040 Handle<ScopeInfo> scope_info = instr->scope_info();
6036 __ Push(scope_info); 6041 __ Push(scope_info);
6037 __ Push(ToRegister(instr->function())); 6042 __ Push(ToRegister(instr->function()));
6038 CallRuntime(Runtime::kPushBlockContext, 2, instr); 6043 CallRuntime(Runtime::kPushBlockContext, 2, instr);
6039 RecordSafepoint(Safepoint::kNoLazyDeopt); 6044 RecordSafepoint(Safepoint::kNoLazyDeopt);
6040 } 6045 }
6041 6046
6042 6047
6043 6048
6044 } } // namespace v8::internal 6049 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm64/lithium-codegen-arm64.h ('k') | src/deoptimizer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698