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 #ifndef RUNTIME_VM_CODE_DESCRIPTORS_H_ | 5 #ifndef RUNTIME_VM_CODE_DESCRIPTORS_H_ |
6 #define RUNTIME_VM_CODE_DESCRIPTORS_H_ | 6 #define RUNTIME_VM_CODE_DESCRIPTORS_H_ |
7 | 7 |
8 #include "vm/ast.h" | 8 #include "vm/ast.h" |
9 #include "vm/datastream.h" | 9 #include "vm/datastream.h" |
10 #include "vm/globals.h" | 10 #include "vm/globals.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 private: | 36 private: |
37 GrowableArray<uint8_t> encoded_data_; | 37 GrowableArray<uint8_t> encoded_data_; |
38 | 38 |
39 intptr_t prev_pc_offset; | 39 intptr_t prev_pc_offset; |
40 intptr_t prev_deopt_id; | 40 intptr_t prev_deopt_id; |
41 intptr_t prev_token_pos; | 41 intptr_t prev_token_pos; |
42 | 42 |
43 DISALLOW_COPY_AND_ASSIGN(DescriptorList); | 43 DISALLOW_COPY_AND_ASSIGN(DescriptorList); |
44 }; | 44 }; |
45 | 45 |
46 | |
47 class StackMapTableBuilder : public ZoneAllocated { | 46 class StackMapTableBuilder : public ZoneAllocated { |
48 public: | 47 public: |
49 StackMapTableBuilder() | 48 StackMapTableBuilder() |
50 : stack_map_(StackMap::ZoneHandle()), | 49 : stack_map_(StackMap::ZoneHandle()), |
51 list_(GrowableObjectArray::ZoneHandle( | 50 list_(GrowableObjectArray::ZoneHandle( |
52 GrowableObjectArray::New(Heap::kOld))) {} | 51 GrowableObjectArray::New(Heap::kOld))) {} |
53 ~StackMapTableBuilder() {} | 52 ~StackMapTableBuilder() {} |
54 | 53 |
55 void AddEntry(intptr_t pc_offset, | 54 void AddEntry(intptr_t pc_offset, |
56 BitmapBuilder* bitmap, | 55 BitmapBuilder* bitmap, |
57 intptr_t register_bit_count); | 56 intptr_t register_bit_count); |
58 | 57 |
59 bool Verify(); | 58 bool Verify(); |
60 | 59 |
61 RawArray* FinalizeStackMaps(const Code& code); | 60 RawArray* FinalizeStackMaps(const Code& code); |
62 | 61 |
63 private: | 62 private: |
64 intptr_t Length() const { return list_.Length(); } | 63 intptr_t Length() const { return list_.Length(); } |
65 RawStackMap* MapAt(intptr_t index) const; | 64 RawStackMap* MapAt(intptr_t index) const; |
66 | 65 |
67 StackMap& stack_map_; | 66 StackMap& stack_map_; |
68 GrowableObjectArray& list_; | 67 GrowableObjectArray& list_; |
69 DISALLOW_COPY_AND_ASSIGN(StackMapTableBuilder); | 68 DISALLOW_COPY_AND_ASSIGN(StackMapTableBuilder); |
70 }; | 69 }; |
71 | 70 |
72 | |
73 class ExceptionHandlerList : public ZoneAllocated { | 71 class ExceptionHandlerList : public ZoneAllocated { |
74 public: | 72 public: |
75 struct HandlerDesc { | 73 struct HandlerDesc { |
76 intptr_t outer_try_index; // Try block in which this try block is nested. | 74 intptr_t outer_try_index; // Try block in which this try block is nested. |
77 intptr_t pc_offset; // Handler PC offset value. | 75 intptr_t pc_offset; // Handler PC offset value. |
78 TokenPosition token_pos; // Token position of handler. | 76 TokenPosition token_pos; // Token position of handler. |
79 bool is_generated; // False if this is directly from Dart code. | 77 bool is_generated; // False if this is directly from Dart code. |
80 const Array* handler_types; // Catch clause guards. | 78 const Array* handler_types; // Catch clause guards. |
81 bool needs_stacktrace; | 79 bool needs_stacktrace; |
82 }; | 80 }; |
(...skipping 27 matching lines...) Expand all Loading... |
110 list_[try_index].outer_try_index = outer_try_index; | 108 list_[try_index].outer_try_index = outer_try_index; |
111 ASSERT(list_[try_index].pc_offset == ExceptionHandlers::kInvalidPcOffset); | 109 ASSERT(list_[try_index].pc_offset == ExceptionHandlers::kInvalidPcOffset); |
112 list_[try_index].pc_offset = pc_offset; | 110 list_[try_index].pc_offset = pc_offset; |
113 list_[try_index].token_pos = token_pos; | 111 list_[try_index].token_pos = token_pos; |
114 list_[try_index].is_generated = is_generated; | 112 list_[try_index].is_generated = is_generated; |
115 ASSERT(handler_types.IsZoneHandle()); | 113 ASSERT(handler_types.IsZoneHandle()); |
116 list_[try_index].handler_types = &handler_types; | 114 list_[try_index].handler_types = &handler_types; |
117 list_[try_index].needs_stacktrace |= needs_stacktrace; | 115 list_[try_index].needs_stacktrace |= needs_stacktrace; |
118 } | 116 } |
119 | 117 |
120 | |
121 // Called by rethrows, to mark their enclosing handlers. | 118 // Called by rethrows, to mark their enclosing handlers. |
122 void SetNeedsStackTrace(intptr_t try_index) { | 119 void SetNeedsStackTrace(intptr_t try_index) { |
123 // Rethrows can be generated outside a try by the compiler. | 120 // Rethrows can be generated outside a try by the compiler. |
124 if (try_index == CatchClauseNode::kInvalidTryIndex) { | 121 if (try_index == CatchClauseNode::kInvalidTryIndex) { |
125 return; | 122 return; |
126 } | 123 } |
127 ASSERT(try_index >= 0); | 124 ASSERT(try_index >= 0); |
128 while (Length() <= try_index) { | 125 while (Length() <= try_index) { |
129 AddPlaceHolder(); | 126 AddPlaceHolder(); |
130 } | 127 } |
131 list_[try_index].needs_stacktrace = true; | 128 list_[try_index].needs_stacktrace = true; |
132 } | 129 } |
133 | 130 |
134 | |
135 static bool ContainsDynamic(const Array& array) { | 131 static bool ContainsDynamic(const Array& array) { |
136 for (intptr_t i = 0; i < array.Length(); i++) { | 132 for (intptr_t i = 0; i < array.Length(); i++) { |
137 if (array.At(i) == Type::DynamicType()) { | 133 if (array.At(i) == Type::DynamicType()) { |
138 return true; | 134 return true; |
139 } | 135 } |
140 } | 136 } |
141 return false; | 137 return false; |
142 } | 138 } |
143 | 139 |
144 RawExceptionHandlers* FinalizeExceptionHandlers(uword entry_point) const; | 140 RawExceptionHandlers* FinalizeExceptionHandlers(uword entry_point) const; |
145 | 141 |
146 private: | 142 private: |
147 GrowableArray<struct HandlerDesc> list_; | 143 GrowableArray<struct HandlerDesc> list_; |
148 DISALLOW_COPY_AND_ASSIGN(ExceptionHandlerList); | 144 DISALLOW_COPY_AND_ASSIGN(ExceptionHandlerList); |
149 }; | 145 }; |
150 | 146 |
151 | |
152 // An encoded move from stack/constant to stack performed | 147 // An encoded move from stack/constant to stack performed |
153 struct CatchEntryStatePair { | 148 struct CatchEntryStatePair { |
154 enum { kCatchEntryStateIsMove = 1, kCatchEntryStateDestShift = 1 }; | 149 enum { kCatchEntryStateIsMove = 1, kCatchEntryStateDestShift = 1 }; |
155 | 150 |
156 intptr_t src, dest; | 151 intptr_t src, dest; |
157 | 152 |
158 static CatchEntryStatePair FromConstant(intptr_t pool_id, | 153 static CatchEntryStatePair FromConstant(intptr_t pool_id, |
159 intptr_t dest_slot) { | 154 intptr_t dest_slot) { |
160 CatchEntryStatePair pair; | 155 CatchEntryStatePair pair; |
161 pair.src = pool_id; | 156 pair.src = pool_id; |
162 pair.dest = (dest_slot << kCatchEntryStateDestShift); | 157 pair.dest = (dest_slot << kCatchEntryStateDestShift); |
163 return pair; | 158 return pair; |
164 } | 159 } |
165 | 160 |
166 static CatchEntryStatePair FromMove(intptr_t src_slot, intptr_t dest_slot) { | 161 static CatchEntryStatePair FromMove(intptr_t src_slot, intptr_t dest_slot) { |
167 CatchEntryStatePair pair; | 162 CatchEntryStatePair pair; |
168 pair.src = src_slot; | 163 pair.src = src_slot; |
169 pair.dest = | 164 pair.dest = |
170 (dest_slot << kCatchEntryStateDestShift) | kCatchEntryStateIsMove; | 165 (dest_slot << kCatchEntryStateDestShift) | kCatchEntryStateIsMove; |
171 return pair; | 166 return pair; |
172 } | 167 } |
173 | 168 |
174 bool operator==(const CatchEntryStatePair& rhs) { | 169 bool operator==(const CatchEntryStatePair& rhs) { |
175 return src == rhs.src && dest == rhs.dest; | 170 return src == rhs.src && dest == rhs.dest; |
176 } | 171 } |
177 }; | 172 }; |
178 | 173 |
179 | |
180 // Used to construct CatchEntryState metadata for AoT mode of compilation. | 174 // Used to construct CatchEntryState metadata for AoT mode of compilation. |
181 class CatchEntryStateMapBuilder : public ZoneAllocated { | 175 class CatchEntryStateMapBuilder : public ZoneAllocated { |
182 public: | 176 public: |
183 CatchEntryStateMapBuilder(); | 177 CatchEntryStateMapBuilder(); |
184 | 178 |
185 void NewMapping(intptr_t pc_offset); | 179 void NewMapping(intptr_t pc_offset); |
186 void AppendMove(intptr_t src_slot, intptr_t dest_slot); | 180 void AppendMove(intptr_t src_slot, intptr_t dest_slot); |
187 void AppendConstant(intptr_t pool_id, intptr_t dest_slot); | 181 void AppendConstant(intptr_t pool_id, intptr_t dest_slot); |
188 void EndMapping(); | 182 void EndMapping(); |
189 RawTypedData* FinalizeCatchEntryStateMap(); | 183 RawTypedData* FinalizeCatchEntryStateMap(); |
190 | 184 |
191 private: | 185 private: |
192 class TrieNode; | 186 class TrieNode; |
193 | 187 |
194 Zone* zone_; | 188 Zone* zone_; |
195 TrieNode* root_; | 189 TrieNode* root_; |
196 intptr_t current_pc_offset_; | 190 intptr_t current_pc_offset_; |
197 GrowableArray<CatchEntryStatePair> moves_; | 191 GrowableArray<CatchEntryStatePair> moves_; |
198 uint8_t* buffer_; | 192 uint8_t* buffer_; |
199 WriteStream stream_; | 193 WriteStream stream_; |
200 | 194 |
201 DISALLOW_COPY_AND_ASSIGN(CatchEntryStateMapBuilder); | 195 DISALLOW_COPY_AND_ASSIGN(CatchEntryStateMapBuilder); |
202 }; | 196 }; |
203 | 197 |
204 | |
205 // A CodeSourceMap maps from pc offsets to a stack of inlined functions and | 198 // A CodeSourceMap maps from pc offsets to a stack of inlined functions and |
206 // their positions. This is encoded as a little bytecode that pushes and pops | 199 // their positions. This is encoded as a little bytecode that pushes and pops |
207 // functions and changes the top function's position as the PC advances. | 200 // functions and changes the top function's position as the PC advances. |
208 // Decoding happens by running this bytecode until we reach the desired PC. | 201 // Decoding happens by running this bytecode until we reach the desired PC. |
209 // | 202 // |
210 // The implementation keeps track of two sets of state: one written to the byte | 203 // The implementation keeps track of two sets of state: one written to the byte |
211 // stream and one that is buffered. On the JIT, this buffering effectively gives | 204 // stream and one that is buffered. On the JIT, this buffering effectively gives |
212 // us a peephole optimization that merges adjacent advance PC bytecodes. On AOT, | 205 // us a peephole optimization that merges adjacent advance PC bytecodes. On AOT, |
213 // this allows to skip encoding our position until we reach a PC where we might | 206 // this allows to skip encoding our position until we reach a PC where we might |
214 // throw. | 207 // throw. |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 const GrowableObjectArray& inlined_functions_; | 293 const GrowableObjectArray& inlined_functions_; |
301 | 294 |
302 uint8_t* buffer_; | 295 uint8_t* buffer_; |
303 WriteStream stream_; | 296 WriteStream stream_; |
304 | 297 |
305 const bool stack_traces_only_; | 298 const bool stack_traces_only_; |
306 | 299 |
307 DISALLOW_COPY_AND_ASSIGN(CodeSourceMapBuilder); | 300 DISALLOW_COPY_AND_ASSIGN(CodeSourceMapBuilder); |
308 }; | 301 }; |
309 | 302 |
310 | |
311 class CodeSourceMapReader : public ValueObject { | 303 class CodeSourceMapReader : public ValueObject { |
312 public: | 304 public: |
313 CodeSourceMapReader(const CodeSourceMap& map, | 305 CodeSourceMapReader(const CodeSourceMap& map, |
314 const Array& functions, | 306 const Array& functions, |
315 const Function& root) | 307 const Function& root) |
316 : map_(map), functions_(functions), root_(root) {} | 308 : map_(map), functions_(functions), root_(root) {} |
317 | 309 |
318 void GetInlinedFunctionsAt(int32_t pc_offset, | 310 void GetInlinedFunctionsAt(int32_t pc_offset, |
319 GrowableArray<const Function*>* function_stack, | 311 GrowableArray<const Function*>* function_stack, |
320 GrowableArray<TokenPosition>* token_positions); | 312 GrowableArray<TokenPosition>* token_positions); |
321 NOT_IN_PRODUCT(void PrintJSONInlineIntervals(JSONObject* jsobj)); | 313 NOT_IN_PRODUCT(void PrintJSONInlineIntervals(JSONObject* jsobj)); |
322 void DumpInlineIntervals(uword start); | 314 void DumpInlineIntervals(uword start); |
323 void DumpSourcePositions(uword start); | 315 void DumpSourcePositions(uword start); |
324 | 316 |
325 private: | 317 private: |
326 const CodeSourceMap& map_; | 318 const CodeSourceMap& map_; |
327 const Array& functions_; | 319 const Array& functions_; |
328 const Function& root_; | 320 const Function& root_; |
329 | 321 |
330 DISALLOW_COPY_AND_ASSIGN(CodeSourceMapReader); | 322 DISALLOW_COPY_AND_ASSIGN(CodeSourceMapReader); |
331 }; | 323 }; |
332 | 324 |
333 } // namespace dart | 325 } // namespace dart |
334 | 326 |
335 #endif // RUNTIME_VM_CODE_DESCRIPTORS_H_ | 327 #endif // RUNTIME_VM_CODE_DESCRIPTORS_H_ |
OLD | NEW |