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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/hydrogen-range-analysis.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/hydrogen-range-analysis.cc
diff --git a/src/hydrogen-range-analysis.cc b/src/hydrogen-range-analysis.cc
index ed254db19c433f3588a08dd442096ec3e4fa45d5..76fd5f35f285c9889fe7a4f5fadff3e7ecf8e13c 100644
--- a/src/hydrogen-range-analysis.cc
+++ b/src/hydrogen-range-analysis.cc
@@ -31,6 +31,20 @@ namespace v8 {
namespace internal {
+class Pending {
+ public:
+ Pending(HBasicBlock* block, int last_changed_range)
+ : block_(block), last_changed_range_(last_changed_range) {}
+
+ HBasicBlock* block() const { return block_; }
+ int last_changed_range() const { return last_changed_range_; }
+
+ private:
+ HBasicBlock* block_;
+ int last_changed_range_;
+};
+
+
void HRangeAnalysisPhase::TraceRange(const char* msg, ...) {
if (FLAG_trace_range) {
va_list arguments;
@@ -41,37 +55,52 @@ void HRangeAnalysisPhase::TraceRange(const char* msg, ...) {
}
-void HRangeAnalysisPhase::Analyze(HBasicBlock* block) {
- TraceRange("Analyzing block B%d\n", block->block_id());
-
- int last_changed_range = changed_ranges_.length() - 1;
+void HRangeAnalysisPhase::Run() {
+ HBasicBlock* block(graph()->entry_block());
+ ZoneList<Pending> stack(graph()->blocks()->length(), zone());
+ while (block != NULL) {
+ TraceRange("Analyzing block B%d\n", block->block_id());
- // Infer range based on control flow.
- if (block->predecessors()->length() == 1) {
- HBasicBlock* pred = block->predecessors()->first();
- if (pred->end()->IsCompareNumericAndBranch()) {
- InferControlFlowRange(HCompareNumericAndBranch::cast(pred->end()),
- block);
+ // Infer range based on control flow.
+ if (block->predecessors()->length() == 1) {
+ HBasicBlock* pred = block->predecessors()->first();
+ if (pred->end()->IsCompareNumericAndBranch()) {
+ InferControlFlowRange(HCompareNumericAndBranch::cast(pred->end()),
+ block);
+ }
}
- }
- // Process phi instructions.
- for (int i = 0; i < block->phis()->length(); ++i) {
- HPhi* phi = block->phis()->at(i);
- InferRange(phi);
- }
+ // Process phi instructions.
+ for (int i = 0; i < block->phis()->length(); ++i) {
+ HPhi* phi = block->phis()->at(i);
+ InferRange(phi);
+ }
- // Go through all instructions of the current block.
- for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
- InferRange(it.Current());
- }
+ // Go through all instructions of the current block.
+ for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
+ InferRange(it.Current());
+ }
- // Continue analysis in all dominated blocks.
- for (int i = 0; i < block->dominated_blocks()->length(); ++i) {
- Analyze(block->dominated_blocks()->at(i));
+ // Continue analysis in all dominated blocks.
+ const ZoneList<HBasicBlock*>* dominated_blocks(block->dominated_blocks());
+ if (!dominated_blocks->is_empty()) {
+ // Continue with first dominated block, and push the
+ // remaining blocks on the stack (in reverse order).
+ int last_changed_range = changed_ranges_.length();
+ for (int i = dominated_blocks->length() - 1; i > 0; --i) {
+ stack.Add(Pending(dominated_blocks->at(i), last_changed_range), zone());
+ }
+ block = dominated_blocks->at(0);
+ } else if (!stack.is_empty()) {
+ // Pop next pending block from stack.
+ Pending pending = stack.RemoveLast();
+ RollBackTo(pending.last_changed_range());
+ block = pending.block();
+ } else {
+ // All blocks done.
+ block = NULL;
+ }
}
-
- RollBackTo(last_changed_range);
}
@@ -140,10 +169,11 @@ void HRangeAnalysisPhase::InferRange(HValue* value) {
void HRangeAnalysisPhase::RollBackTo(int index) {
- for (int i = index + 1; i < changed_ranges_.length(); ++i) {
+ ASSERT(index <= changed_ranges_.length());
+ for (int i = index; i < changed_ranges_.length(); ++i) {
changed_ranges_[i]->RemoveLastAddedRange();
}
- changed_ranges_.Rewind(index + 1);
+ changed_ranges_.Rewind(index);
}
« 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