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