OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/code_descriptors.h" | 5 #include "vm/code_descriptors.h" |
6 | 6 |
7 #include "vm/log.h" | 7 #include "vm/log.h" |
8 | 8 |
9 namespace dart { | 9 namespace dart { |
10 | 10 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 | 118 |
119 | 119 |
120 static uint8_t* zone_allocator(uint8_t* ptr, | 120 static uint8_t* zone_allocator(uint8_t* ptr, |
121 intptr_t old_size, | 121 intptr_t old_size, |
122 intptr_t new_size) { | 122 intptr_t new_size) { |
123 Zone* zone = Thread::Current()->zone(); | 123 Zone* zone = Thread::Current()->zone(); |
124 return zone->Realloc<uint8_t>(ptr, old_size, new_size); | 124 return zone->Realloc<uint8_t>(ptr, old_size, new_size); |
125 } | 125 } |
126 | 126 |
127 | 127 |
128 class CatchEntryStateMapBuilder::TrieNode : public ZoneAllocated { | |
129 public: | |
130 TrieNode() : pair_(), entry_state_offset_(-1) {} | |
131 TrieNode(CatchEntryStatePair pair, intptr_t index) | |
132 : pair_(pair), entry_state_offset_(index) {} | |
133 | |
134 intptr_t Offset() { return entry_state_offset_; } | |
135 | |
136 TrieNode* Insert(TrieNode* node) { | |
137 children_.Add(node); | |
138 return node; | |
139 } | |
140 | |
141 TrieNode* Follow(CatchEntryStatePair next) { | |
142 for (intptr_t i = 0; i < children_.length(); i++) { | |
143 if (children_[i]->pair_ == next) return children_[i]; | |
144 } | |
145 return NULL; | |
146 } | |
147 | |
148 private: | |
149 CatchEntryStatePair pair_; | |
150 const intptr_t entry_state_offset_; | |
151 GrowableArray<TrieNode*> children_; | |
152 }; | |
153 | |
154 CatchEntryStateMapBuilder::CatchEntryStateMapBuilder() | |
155 : zone_(Thread::Current()->zone()), | |
156 root_(new TrieNode()), | |
157 current_pc_offset_(0), | |
158 buffer_(NULL), | |
159 stream_(&buffer_, zone_allocator, 64) {} | |
160 | |
161 | |
162 void CatchEntryStateMapBuilder::AppendMove(intptr_t src_slot, | |
163 intptr_t dest_slot) { | |
164 moves_.Add(CatchEntryStatePair::FromMove(src_slot, dest_slot)); | |
165 } | |
166 | |
167 | |
168 void CatchEntryStateMapBuilder::AppendConstant(intptr_t pool_id, | |
169 intptr_t dest_slot) { | |
170 moves_.Add(CatchEntryStatePair::FromConstant(pool_id, dest_slot)); | |
171 } | |
172 | |
173 | |
174 void CatchEntryStateMapBuilder::NewMapping(intptr_t pc_offset) { | |
175 moves_.Clear(); | |
176 current_pc_offset_ = pc_offset; | |
177 } | |
178 | |
179 | |
180 void CatchEntryStateMapBuilder::EndMapping() { | |
181 intptr_t suffix_length = 0; | |
182 TrieNode* suffix = root_; | |
183 // Find the largest common suffix, get the last node of the path. | |
184 for (intptr_t i = moves_.length() - 1; i >= 0; i--) { | |
185 TrieNode* n = suffix->Follow(moves_[i]); | |
186 if (n == NULL) break; | |
187 suffix_length++; | |
188 suffix = n; | |
189 } | |
190 intptr_t length = moves_.length() - suffix_length; | |
191 intptr_t current_offset = stream_.bytes_written(); | |
192 | |
193 typedef WriteStream::Raw<sizeof(intptr_t), intptr_t> Writer; | |
194 Writer::Write(&stream_, current_pc_offset_); | |
195 Writer::Write(&stream_, length); | |
196 Writer::Write(&stream_, suffix_length); | |
197 Writer::Write(&stream_, suffix->Offset()); | |
198 | |
199 // Write the unshared part, adding it to the trie. | |
200 TrieNode* node = suffix; | |
201 for (intptr_t i = length - 1; i >= 0; i--) { | |
202 Writer::Write(&stream_, moves_[i].src); | |
203 Writer::Write(&stream_, moves_[i].dest); | |
204 | |
205 TrieNode* child = new (zone_) TrieNode(moves_[i], current_offset); | |
206 node->Insert(child); | |
207 node = child; | |
208 } | |
209 } | |
210 | |
211 | |
212 RawTypedData* CatchEntryStateMapBuilder::FinalizeCatchEntryStateMap() { | |
213 TypedData& td = TypedData::Handle(TypedData::New( | |
214 kTypedDataInt8ArrayCid, stream_.bytes_written(), Heap::kOld)); | |
215 NoSafepointScope no_safepoint; | |
216 uint8_t* dest = reinterpret_cast<uint8_t*>(td.DataAddr(0)); | |
217 uint8_t* src = stream_.buffer(); | |
218 for (intptr_t i = 0; i < stream_.bytes_written(); i++) { | |
219 dest[i] = src[i]; | |
220 } | |
221 return td.raw(); | |
222 } | |
223 | |
224 | |
225 const TokenPosition CodeSourceMapBuilder::kInitialPosition = | 128 const TokenPosition CodeSourceMapBuilder::kInitialPosition = |
226 TokenPosition::kDartCodePrologue; | 129 TokenPosition::kDartCodePrologue; |
227 | 130 |
228 | 131 |
229 CodeSourceMapBuilder::CodeSourceMapBuilder( | 132 CodeSourceMapBuilder::CodeSourceMapBuilder( |
230 bool stack_traces_only, | 133 bool stack_traces_only, |
231 const GrowableArray<intptr_t>& caller_inline_id, | 134 const GrowableArray<intptr_t>& caller_inline_id, |
232 const GrowableArray<TokenPosition>& inline_id_to_token_pos, | 135 const GrowableArray<TokenPosition>& inline_id_to_token_pos, |
233 const GrowableArray<const Function*>& inline_id_to_function) | 136 const GrowableArray<const Function*>& inline_id_to_function) |
234 : buffered_pc_offset_(0), | 137 : buffered_pc_offset_(0), |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
640 break; | 543 break; |
641 } | 544 } |
642 default: | 545 default: |
643 UNREACHABLE(); | 546 UNREACHABLE(); |
644 } | 547 } |
645 } | 548 } |
646 THR_Print("}\n"); | 549 THR_Print("}\n"); |
647 } | 550 } |
648 | 551 |
649 } // namespace dart | 552 } // namespace dart |
OLD | NEW |