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 |
128 const TokenPosition CodeSourceMapBuilder::kInitialPosition = | 225 const TokenPosition CodeSourceMapBuilder::kInitialPosition = |
129 TokenPosition::kDartCodePrologue; | 226 TokenPosition::kDartCodePrologue; |
130 | 227 |
131 | 228 |
132 CodeSourceMapBuilder::CodeSourceMapBuilder( | 229 CodeSourceMapBuilder::CodeSourceMapBuilder( |
133 bool stack_traces_only, | 230 bool stack_traces_only, |
134 const GrowableArray<intptr_t>& caller_inline_id, | 231 const GrowableArray<intptr_t>& caller_inline_id, |
135 const GrowableArray<TokenPosition>& inline_id_to_token_pos, | 232 const GrowableArray<TokenPosition>& inline_id_to_token_pos, |
136 const GrowableArray<const Function*>& inline_id_to_function) | 233 const GrowableArray<const Function*>& inline_id_to_function) |
137 : buffered_pc_offset_(0), | 234 : buffered_pc_offset_(0), |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 break; | 640 break; |
544 } | 641 } |
545 default: | 642 default: |
546 UNREACHABLE(); | 643 UNREACHABLE(); |
547 } | 644 } |
548 } | 645 } |
549 THR_Print("}\n"); | 646 THR_Print("}\n"); |
550 } | 647 } |
551 | 648 |
552 } // namespace dart | 649 } // namespace dart |
OLD | NEW |