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

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: No side-effects in comparisons. 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 class Pending {
35 public:
36 Pending(HBasicBlock* block, int last_changed_range)
37 : block_(block), last_changed_range_(last_changed_range) {}
38
39 HBasicBlock* block() const { return block_; }
40 int last_changed_range() const { return last_changed_range_; }
41
42 private:
43 HBasicBlock* block_;
44 int last_changed_range_;
45 };
46
47
34 void HRangeAnalysisPhase::TraceRange(const char* msg, ...) { 48 void HRangeAnalysisPhase::TraceRange(const char* msg, ...) {
35 if (FLAG_trace_range) { 49 if (FLAG_trace_range) {
36 va_list arguments; 50 va_list arguments;
37 va_start(arguments, msg); 51 va_start(arguments, msg);
38 OS::VPrint(msg, arguments); 52 OS::VPrint(msg, arguments);
39 va_end(arguments); 53 va_end(arguments);
40 } 54 }
41 } 55 }
42 56
43 57
44 void HRangeAnalysisPhase::Analyze(HBasicBlock* block) { 58 void HRangeAnalysisPhase::Run() {
45 TraceRange("Analyzing block B%d\n", block->block_id()); 59 HBasicBlock* block(graph()->entry_block());
60 ZoneList<Pending> stack(graph()->blocks()->length(), zone());
61 while (block != NULL) {
62 TraceRange("Analyzing block B%d\n", block->block_id());
46 63
47 int last_changed_range = changed_ranges_.length() - 1; 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 }
48 72
49 // Infer range based on control flow. 73 // Process phi instructions.
50 if (block->predecessors()->length() == 1) { 74 for (int i = 0; i < block->phis()->length(); ++i) {
51 HBasicBlock* pred = block->predecessors()->first(); 75 HPhi* phi = block->phis()->at(i);
52 if (pred->end()->IsCompareNumericAndBranch()) { 76 InferRange(phi);
53 InferControlFlowRange(HCompareNumericAndBranch::cast(pred->end()), 77 }
54 block); 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() - 1; i > 0; --i) {
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 // Pop next pending block from stack.
96 Pending pending = stack.RemoveLast();
97 RollBackTo(pending.last_changed_range());
98 block = pending.block();
99 } else {
100 // All blocks done.
101 block = NULL;
55 } 102 }
56 } 103 }
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 } 104 }
76 105
77 106
78 void HRangeAnalysisPhase::InferControlFlowRange(HCompareNumericAndBranch* test, 107 void HRangeAnalysisPhase::InferControlFlowRange(HCompareNumericAndBranch* test,
79 HBasicBlock* dest) { 108 HBasicBlock* dest) {
80 ASSERT((test->FirstSuccessor() == dest) == (test->SecondSuccessor() != dest)); 109 ASSERT((test->FirstSuccessor() == dest) == (test->SecondSuccessor() != dest));
81 if (test->representation().IsSmiOrInteger32()) { 110 if (test->representation().IsSmiOrInteger32()) {
82 Token::Value op = test->token(); 111 Token::Value op = test->token();
83 if (test->SecondSuccessor() == dest) { 112 if (test->SecondSuccessor() == dest) {
84 op = Token::NegateCompareOp(op); 113 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", 162 TraceRange("Initial inferred range of %d (%s) set to [%d,%d]\n",
134 value->id(), 163 value->id(),
135 value->Mnemonic(), 164 value->Mnemonic(),
136 range->lower(), 165 range->lower(),
137 range->upper()); 166 range->upper());
138 } 167 }
139 } 168 }
140 169
141 170
142 void HRangeAnalysisPhase::RollBackTo(int index) { 171 void HRangeAnalysisPhase::RollBackTo(int index) {
143 for (int i = index + 1; i < changed_ranges_.length(); ++i) { 172 ASSERT(index <= changed_ranges_.length());
173 for (int i = index; i < changed_ranges_.length(); ++i) {
144 changed_ranges_[i]->RemoveLastAddedRange(); 174 changed_ranges_[i]->RemoveLastAddedRange();
145 } 175 }
146 changed_ranges_.Rewind(index + 1); 176 changed_ranges_.Rewind(index);
147 } 177 }
148 178
149 179
150 void HRangeAnalysisPhase::AddRange(HValue* value, Range* range) { 180 void HRangeAnalysisPhase::AddRange(HValue* value, Range* range) {
151 Range* original_range = value->range(); 181 Range* original_range = value->range();
152 value->AddNewRange(range, graph()->zone()); 182 value->AddNewRange(range, graph()->zone());
153 changed_ranges_.Add(value, zone()); 183 changed_ranges_.Add(value, zone());
154 Range* new_range = value->range(); 184 Range* new_range = value->range();
155 TraceRange("Updated range of %d set to [%d,%d]\n", 185 TraceRange("Updated range of %d set to [%d,%d]\n",
156 value->id(), 186 value->id(),
157 new_range->lower(), 187 new_range->lower(),
158 new_range->upper()); 188 new_range->upper());
159 if (original_range != NULL) { 189 if (original_range != NULL) {
160 TraceRange("Original range was [%d,%d]\n", 190 TraceRange("Original range was [%d,%d]\n",
161 original_range->lower(), 191 original_range->lower(),
162 original_range->upper()); 192 original_range->upper());
163 } 193 }
164 TraceRange("New information was [%d,%d]\n", 194 TraceRange("New information was [%d,%d]\n",
165 range->lower(), 195 range->lower(),
166 range->upper()); 196 range->upper());
167 } 197 }
168 198
169 199
170 } } // namespace v8::internal 200 } } // 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