| 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 |