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

Side by Side Diff: src/hydrogen-range-analysis.cc

Issue 19145002: Fix possible stack overflow in range analysis. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 5 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/hydrogen-range-analysis.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 13 matching lines...) Expand all
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "hydrogen-range-analysis.h" 28 #include "hydrogen-range-analysis.h"
29 29
30 namespace v8 { 30 namespace v8 {
31 namespace internal { 31 namespace internal {
32 32
33 33
34 void HRangeAnalysisPhase::TraceRange(const char* msg, ...) { 34 static void TraceRange(const char* msg, ...) {
Dmitry Lomov (no reviews) 2013/07/15 09:12:06 nit: Why this change? I liked the original one bet
Benedikt Meurer 2013/07/15 09:17:29 Done.
35 if (FLAG_trace_range) { 35 if (FLAG_trace_range) {
36 va_list arguments; 36 va_list arguments;
37 va_start(arguments, msg); 37 va_start(arguments, msg);
38 OS::VPrint(msg, arguments); 38 OS::VPrint(msg, arguments);
39 va_end(arguments); 39 va_end(arguments);
40 } 40 }
41 } 41 }
42 42
43 43
44 void HRangeAnalysisPhase::Analyze(HBasicBlock* block) { 44 class Pending {
45 TraceRange("Analyzing block B%d\n", block->block_id()); 45 public:
46 Pending(HBasicBlock* block, int last_changed_range)
47 : block_(block), last_changed_range_(last_changed_range) {}
46 48
47 int last_changed_range = changed_ranges_.length() - 1; 49 HBasicBlock* block() const { return block_; }
50 int last_changed_range() const { return last_changed_range_; }
48 51
49 // Infer range based on control flow. 52 private:
50 if (block->predecessors()->length() == 1) { 53 HBasicBlock* block_;
51 HBasicBlock* pred = block->predecessors()->first(); 54 int last_changed_range_;
52 if (pred->end()->IsCompareNumericAndBranch()) { 55 };
53 InferControlFlowRange(HCompareNumericAndBranch::cast(pred->end()), 56
54 block); 57
58 void HRangeAnalysisPhase::Run() {
59 HBasicBlock* block(graph()->entry_block());
60 ZoneList<Pending> stack(graph()->blocks()->length(), zone());
61 for (;;) {
Dmitry Lomov (no reviews) 2013/07/15 09:12:06 Can we make the terminating condition for this loo
Benedikt Meurer 2013/07/15 09:17:29 Done.
62 TraceRange("Analyzing block B%d\n", block->block_id());
63
64 // Infer range based on control flow.
65 if (block->predecessors()->length() == 1) {
66 HBasicBlock* pred = block->predecessors()->first();
67 if (pred->end()->IsCompareNumericAndBranch()) {
68 InferControlFlowRange(HCompareNumericAndBranch::cast(pred->end()),
69 block);
70 }
71 }
72
73 // Process phi instructions.
74 for (int i = 0; i < block->phis()->length(); ++i) {
75 HPhi* phi = block->phis()->at(i);
76 InferRange(phi);
77 }
78
79 // Go through all instructions of the current block.
80 for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
81 InferRange(it.Current());
82 }
83
84 // Continue analysis in all dominated blocks.
85 const ZoneList<HBasicBlock*>* dominated_blocks(block->dominated_blocks());
86 if (!dominated_blocks->is_empty()) {
87 // Continue with first dominated block, and push the
88 // remaining blocks on the stack (in reverse order).
89 int last_changed_range = changed_ranges_.length();
90 for (int i = dominated_blocks->length(); --i > 0; ) {
91 stack.Add(Pending(dominated_blocks->at(i), last_changed_range), zone());
92 }
93 block = dominated_blocks->at(0);
94 } else if (stack.is_empty()) {
95 break;
96 } else {
97 // Pop next pending block from stack.
98 Pending pending = stack.RemoveLast();
99 RollBackTo(pending.last_changed_range());
100 block = pending.block();
55 } 101 }
56 } 102 }
57
58 // Process phi instructions.
59 for (int i = 0; i < block->phis()->length(); ++i) {
60 HPhi* phi = block->phis()->at(i);
61 InferRange(phi);
62 }
63
64 // Go through all instructions of the current block.
65 for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
66 InferRange(it.Current());
67 }
68
69 // Continue analysis in all dominated blocks.
70 for (int i = 0; i < block->dominated_blocks()->length(); ++i) {
71 Analyze(block->dominated_blocks()->at(i));
72 }
73
74 RollBackTo(last_changed_range);
75 } 103 }
76 104
77 105
78 void HRangeAnalysisPhase::InferControlFlowRange(HCompareNumericAndBranch* test, 106 void HRangeAnalysisPhase::InferControlFlowRange(HCompareNumericAndBranch* test,
79 HBasicBlock* dest) { 107 HBasicBlock* dest) {
80 ASSERT((test->FirstSuccessor() == dest) == (test->SecondSuccessor() != dest)); 108 ASSERT((test->FirstSuccessor() == dest) == (test->SecondSuccessor() != dest));
81 if (test->representation().IsSmiOrInteger32()) { 109 if (test->representation().IsSmiOrInteger32()) {
82 Token::Value op = test->token(); 110 Token::Value op = test->token();
83 if (test->SecondSuccessor() == dest) { 111 if (test->SecondSuccessor() == dest) {
84 op = Token::NegateCompareOp(op); 112 op = Token::NegateCompareOp(op);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 TraceRange("Initial inferred range of %d (%s) set to [%d,%d]\n", 161 TraceRange("Initial inferred range of %d (%s) set to [%d,%d]\n",
134 value->id(), 162 value->id(),
135 value->Mnemonic(), 163 value->Mnemonic(),
136 range->lower(), 164 range->lower(),
137 range->upper()); 165 range->upper());
138 } 166 }
139 } 167 }
140 168
141 169
142 void HRangeAnalysisPhase::RollBackTo(int index) { 170 void HRangeAnalysisPhase::RollBackTo(int index) {
143 for (int i = index + 1; i < changed_ranges_.length(); ++i) { 171 ASSERT(index <= changed_ranges_.length());
172 for (int i = index; i < changed_ranges_.length(); ++i) {
144 changed_ranges_[i]->RemoveLastAddedRange(); 173 changed_ranges_[i]->RemoveLastAddedRange();
145 } 174 }
146 changed_ranges_.Rewind(index + 1); 175 changed_ranges_.Rewind(index);
147 } 176 }
148 177
149 178
150 void HRangeAnalysisPhase::AddRange(HValue* value, Range* range) { 179 void HRangeAnalysisPhase::AddRange(HValue* value, Range* range) {
151 Range* original_range = value->range(); 180 Range* original_range = value->range();
152 value->AddNewRange(range, graph()->zone()); 181 value->AddNewRange(range, graph()->zone());
153 changed_ranges_.Add(value, zone()); 182 changed_ranges_.Add(value, zone());
154 Range* new_range = value->range(); 183 Range* new_range = value->range();
155 TraceRange("Updated range of %d set to [%d,%d]\n", 184 TraceRange("Updated range of %d set to [%d,%d]\n",
156 value->id(), 185 value->id(),
157 new_range->lower(), 186 new_range->lower(),
158 new_range->upper()); 187 new_range->upper());
159 if (original_range != NULL) { 188 if (original_range != NULL) {
160 TraceRange("Original range was [%d,%d]\n", 189 TraceRange("Original range was [%d,%d]\n",
161 original_range->lower(), 190 original_range->lower(),
162 original_range->upper()); 191 original_range->upper());
163 } 192 }
164 TraceRange("New information was [%d,%d]\n", 193 TraceRange("New information was [%d,%d]\n",
165 range->lower(), 194 range->lower(),
166 range->upper()); 195 range->upper());
167 } 196 }
168 197
169 198
170 } } // namespace v8::internal 199 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen-range-analysis.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698