OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 the V8 project authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "src/compiler/bytecode-analysis.h" | |
6 | |
7 #include "src/interpreter/bytecode-array-reverse-iterator.h" | |
8 #include "src/objects-inl.h" | |
9 | |
10 namespace v8 { | |
11 namespace internal { | |
12 namespace compiler { | |
13 | |
14 BytecodeAnalysis::BytecodeAnalysis(Handle<BytecodeArray> bytecode_array, | |
15 Zone* zone) | |
16 : bytecode_array_(bytecode_array), | |
17 zone_(zone), | |
18 loop_stack_(zone), | |
19 end_to_header_(zone), | |
20 header_to_parent_(zone) {} | |
21 | |
22 void BytecodeAnalysis::Analyze() { | |
23 loop_stack_.push(-1); | |
24 | |
25 interpreter::BytecodeArrayReverseIterator iterator(bytecode_array(), zone()); | |
26 while (!iterator.done()) { | |
27 interpreter::Bytecode bytecode = iterator.current_bytecode(); | |
28 if (bytecode == interpreter::Bytecode::kJumpLoop) { | |
29 PushLoop(iterator.GetJumpTargetOffset(), iterator.current_offset()); | |
30 } else if (iterator.current_offset() == loop_stack_.top()) { | |
31 loop_stack_.pop(); | |
32 } | |
33 iterator.Advance(); | |
34 } | |
35 | |
36 DCHECK_EQ(loop_stack_.size(), 1u); | |
37 DCHECK_EQ(loop_stack_.top(), -1); | |
38 } | |
39 | |
40 void BytecodeAnalysis::PushLoop(int loop_header, int loop_end) { | |
41 DCHECK(loop_header < loop_end); | |
42 DCHECK(loop_stack_.top() < loop_header); | |
Jarin
2016/11/22 11:59:18
Oh, we do not have multiple back-edges anymore?
Leszek Swirski
2016/11/22 17:39:03
Not anymore, ever since we added the JumpLoop byte
| |
43 DCHECK(end_to_header_.find(loop_end) == end_to_header_.end()); | |
44 DCHECK(header_to_parent_.find(loop_header) == header_to_parent_.end()); | |
45 | |
46 end_to_header_.insert(ZoneMap<int, int>::value_type(loop_end, loop_header)); | |
47 header_to_parent_.insert( | |
48 ZoneMap<int, int>::value_type(loop_header, loop_stack_.top())); | |
49 loop_stack_.push(loop_header); | |
50 } | |
51 | |
52 bool BytecodeAnalysis::IsLoopHeader(int offset) const { | |
53 return header_to_parent_.find(offset) != header_to_parent_.end(); | |
54 } | |
55 | |
56 int BytecodeAnalysis::GetLoopOffsetFor(int offset) const { | |
57 auto loop_end_to_header = end_to_header_.lower_bound(offset); | |
58 // If there is no next end => offset is not in a loop. | |
59 if (loop_end_to_header == end_to_header_.end()) { | |
60 return -1; | |
61 } | |
62 // If the header preceeds the offset, this is the loop | |
63 // | |
64 // .> header <--loop_end_to_header | |
65 // | | |
66 // | <--offset | |
67 // | | |
68 // `- end | |
69 if (loop_end_to_header->second <= offset) { | |
70 return loop_end_to_header->second; | |
71 } | |
72 // Otherwise there is a (potentially nested) loop after this offset. | |
73 // | |
74 // <--offset | |
75 // | |
76 // .> header | |
77 // | | |
78 // | .> header <--loop_end_to_header | |
79 // | | | |
80 // | `- end | |
81 // | | |
82 // `- end | |
83 // We just return the parent of the next loop header (might be -1). | |
84 DCHECK(header_to_parent_.upper_bound(offset) != header_to_parent_.end()); | |
85 | |
86 return header_to_parent_.upper_bound(offset)->second; | |
87 } | |
88 | |
89 int BytecodeAnalysis::GetParentLoopFor(int header_offset) const { | |
90 DCHECK(IsLoopHeader(header_offset)); | |
91 | |
92 return header_to_parent_.find(header_offset)->second; | |
93 } | |
94 | |
95 } // namespace compiler | |
96 } // namespace internal | |
97 } // namespace v8 | |
OLD | NEW |