Chromium Code Reviews| 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/code_generator.h" | 9 #include "vm/code_generator.h" |
| 10 #include "vm/globals.h" | 10 #include "vm/globals.h" |
| 11 #include "vm/growable_array.h" | 11 #include "vm/growable_array.h" |
| 12 #include "vm/object.h" | 12 #include "vm/object.h" |
| 13 #include "vm/log.h" | |
| 13 | 14 |
| 14 namespace dart { | 15 namespace dart { |
| 15 | 16 |
| 16 class DescriptorList : public ZoneAllocated { | 17 class DescriptorList : public ZoneAllocated { |
| 17 public: | 18 public: |
| 18 explicit DescriptorList(intptr_t initial_capacity) | 19 explicit DescriptorList(intptr_t initial_capacity) |
| 19 : encoded_data_(initial_capacity), | 20 : encoded_data_(initial_capacity), |
| 20 prev_pc_offset(0), | 21 prev_pc_offset(0), |
| 21 prev_deopt_id(0), | 22 prev_deopt_id(0), |
| 22 prev_token_pos(0) {} | 23 prev_token_pos(0) {} |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 132 } | 133 } |
| 133 | 134 |
| 134 RawExceptionHandlers* FinalizeExceptionHandlers(uword entry_point) const; | 135 RawExceptionHandlers* FinalizeExceptionHandlers(uword entry_point) const; |
| 135 | 136 |
| 136 private: | 137 private: |
| 137 GrowableArray<struct HandlerDesc> list_; | 138 GrowableArray<struct HandlerDesc> list_; |
| 138 DISALLOW_COPY_AND_ASSIGN(ExceptionHandlerList); | 139 DISALLOW_COPY_AND_ASSIGN(ExceptionHandlerList); |
| 139 }; | 140 }; |
| 140 | 141 |
| 141 | 142 |
| 143 // A CodeSourceMap maps from pc offsets to a stack inlined functions and their | |
|
Florian Schneider
2017/02/08 18:55:20
stack *of* inlined
rmacnak
2017/02/08 19:24:26
Done.
| |
| 144 // positions. This is encoded as a little bytecode that pushes and pops | |
| 145 // functions and changes the top function's position as the PC advances. | |
| 146 // Decoding happens by running this bytecode until we reach the desired PC. | |
| 147 // | |
| 148 // The implementation keeps track of two sets of state: one written to the byte | |
| 149 // stream and one that is buffered. On the JIT, this buffering effectively gives | |
| 150 // us a peephole optimization that merges adjacent advance PC bytecodes. On AOT, | |
| 151 // this allows to skip encoding our position until we reach a PC where we might | |
| 152 // throw. | |
| 142 class CodeSourceMapBuilder : public ZoneAllocated { | 153 class CodeSourceMapBuilder : public ZoneAllocated { |
| 143 public: | 154 public: |
| 144 CodeSourceMapBuilder( | 155 CodeSourceMapBuilder( |
| 156 bool stack_traces_only, | |
| 145 const GrowableArray<intptr_t>& caller_inline_id, | 157 const GrowableArray<intptr_t>& caller_inline_id, |
| 146 const GrowableArray<TokenPosition>& inline_id_to_token_pos, | 158 const GrowableArray<TokenPosition>& inline_id_to_token_pos, |
| 147 const GrowableArray<const Function*>& inline_id_to_function); | 159 const GrowableArray<const Function*>& inline_id_to_function); |
| 148 | 160 |
| 149 // The position at which a function implicitly starts, for both the root and | 161 // The position at which a function implicitly starts, for both the root and |
| 150 // after a push bytecode. We use the classifying position kDartCodePrologue | 162 // after a push bytecode. We use the classifying position kDartCodePrologue |
| 151 // since it is the most common. | 163 // since it is the most common. |
| 152 static const TokenPosition kInitialPosition; | 164 static const TokenPosition kInitialPosition; |
| 153 | 165 |
| 154 static const uint8_t kChangePosition = 0; | 166 static const uint8_t kChangePosition = 0; |
| 155 static const uint8_t kAdvancePC = 1; | 167 static const uint8_t kAdvancePC = 1; |
| 156 static const uint8_t kPushFunction = 2; | 168 static const uint8_t kPushFunction = 2; |
| 157 static const uint8_t kPopFunction = 3; | 169 static const uint8_t kPopFunction = 3; |
| 158 | 170 |
| 159 void StartInliningInterval(int32_t pc_offset, intptr_t inline_id); | 171 void StartInliningInterval(int32_t pc_offset, intptr_t inline_id); |
| 160 void BeginCodeSourceRange(int32_t pc_offset); | 172 void BeginCodeSourceRange(int32_t pc_offset); |
| 161 void EndCodeSourceRange(int32_t pc_offset, TokenPosition pos); | 173 void EndCodeSourceRange(int32_t pc_offset, TokenPosition pos); |
| 174 void NoteDescriptor(RawPcDescriptors::Kind kind, | |
| 175 int32_t pc_offset, | |
| 176 TokenPosition pos); | |
| 162 | 177 |
| 163 RawArray* InliningIdToFunction(); | 178 RawArray* InliningIdToFunction(); |
| 164 RawCodeSourceMap* Finalize(); | 179 RawCodeSourceMap* Finalize(); |
| 165 | 180 |
| 166 private: | 181 private: |
| 167 void EmitPosition(TokenPosition pos) { | 182 void BufferChangePosition(TokenPosition pos) { |
| 168 FlushPeephole(); | 183 buffered_token_pos_stack_.Last() = pos; |
| 184 } | |
| 185 void WriteChangePosition(TokenPosition pos) { | |
| 186 // THR_Print(" Position %ld\n", pos.value()); | |
|
Florian Schneider
2017/02/08 18:55:20
Remove debug printing.
rmacnak
2017/02/08 19:24:26
Done.
| |
| 169 stream_.Write<uint8_t>(kChangePosition); | 187 stream_.Write<uint8_t>(kChangePosition); |
| 170 stream_.Write<int32_t>(static_cast<int32_t>(pos.value())); | 188 stream_.Write<int32_t>(static_cast<int32_t>(pos.value())); |
| 189 written_token_pos_stack_.Last() = pos; | |
| 171 } | 190 } |
| 172 void EmitAdvancePC(int32_t distance) { advance_pc_peephole_ += distance; } | 191 void BufferAdvancePC(int32_t distance) { buffered_pc_offset_ += distance; } |
| 173 void FlushPeephole() { | 192 void WriteAdvancePC(int32_t distance) { |
| 174 if (advance_pc_peephole_ != 0) { | 193 // THR_Print(" Advance %d\n", distance); |
| 175 stream_.Write<uint8_t>(kAdvancePC); | 194 stream_.Write<uint8_t>(kAdvancePC); |
| 176 stream_.Write<int32_t>(advance_pc_peephole_); | 195 stream_.Write<int32_t>(distance); |
| 177 advance_pc_peephole_ = 0; | 196 written_pc_offset_ += distance; |
| 178 } | |
| 179 } | 197 } |
| 180 void EmitPush(intptr_t inline_id) { | 198 void BufferPush(intptr_t inline_id) { |
| 181 FlushPeephole(); | 199 buffered_inline_id_stack_.Add(inline_id); |
| 200 buffered_token_pos_stack_.Add(kInitialPosition); | |
| 201 } | |
| 202 void WritePush(intptr_t inline_id) { | |
| 203 // THR_Print(" Push %" Pd "\n", inline_id); | |
|
Florian Schneider
2017/02/08 18:55:20
Remove debug printing
| |
| 182 stream_.Write<uint8_t>(kPushFunction); | 204 stream_.Write<uint8_t>(kPushFunction); |
| 183 stream_.Write<int32_t>(inline_id); | 205 stream_.Write<int32_t>(inline_id); |
| 206 written_inline_id_stack_.Add(inline_id); | |
| 207 written_token_pos_stack_.Add(kInitialPosition); | |
| 184 } | 208 } |
| 185 void EmitPop() { | 209 void BufferPop() { |
| 186 FlushPeephole(); | 210 buffered_inline_id_stack_.RemoveLast(); |
| 211 buffered_token_pos_stack_.RemoveLast(); | |
| 212 } | |
| 213 void WritePop() { | |
| 187 stream_.Write<uint8_t>(kPopFunction); | 214 stream_.Write<uint8_t>(kPopFunction); |
| 215 // THR_Print(" Pop\n"); | |
|
Florian Schneider
2017/02/08 18:55:20
Remove debug printing.
| |
| 216 written_inline_id_stack_.RemoveLast(); | |
| 217 written_token_pos_stack_.RemoveLast(); | |
| 188 } | 218 } |
| 189 | 219 |
| 190 bool IsOnStack(intptr_t inline_id) { | 220 void FlushBuffer(); |
| 191 for (intptr_t i = 0; i < inline_id_stack_.length(); i++) { | 221 void FlushBufferStack(); |
| 192 if (inline_id_stack_[i] == inline_id) { | 222 void FlushBufferPosition(); |
| 193 return true; | 223 void FlushBufferPC(); |
| 194 } | 224 |
| 225 bool IsOnBufferedStack(intptr_t inline_id) { | |
| 226 for (intptr_t i = 0; i < buffered_inline_id_stack_.length(); i++) { | |
| 227 if (buffered_inline_id_stack_[i] == inline_id) return true; | |
| 195 } | 228 } |
| 196 return false; | 229 return false; |
| 197 } | 230 } |
| 198 | 231 |
| 199 intptr_t pc_offset_; | 232 intptr_t buffered_pc_offset_; |
| 200 intptr_t advance_pc_peephole_; | 233 GrowableArray<intptr_t> buffered_inline_id_stack_; |
| 201 GrowableArray<intptr_t> inline_id_stack_; | 234 GrowableArray<TokenPosition> buffered_token_pos_stack_; |
| 202 GrowableArray<TokenPosition> token_pos_stack_; | 235 |
| 236 intptr_t written_pc_offset_; | |
| 237 GrowableArray<intptr_t> written_inline_id_stack_; | |
| 238 GrowableArray<TokenPosition> written_token_pos_stack_; | |
| 203 | 239 |
| 204 const GrowableArray<intptr_t>& caller_inline_id_; | 240 const GrowableArray<intptr_t>& caller_inline_id_; |
| 205 const GrowableArray<TokenPosition>& inline_id_to_token_pos_; | 241 const GrowableArray<TokenPosition>& inline_id_to_token_pos_; |
| 206 const GrowableArray<const Function*>& inline_id_to_function_; | 242 const GrowableArray<const Function*>& inline_id_to_function_; |
| 207 | 243 |
| 208 uint8_t* buffer_; | 244 uint8_t* buffer_; |
| 209 WriteStream stream_; | 245 WriteStream stream_; |
| 210 | 246 |
| 247 const bool stack_traces_only_; | |
| 248 | |
| 211 DISALLOW_COPY_AND_ASSIGN(CodeSourceMapBuilder); | 249 DISALLOW_COPY_AND_ASSIGN(CodeSourceMapBuilder); |
| 212 }; | 250 }; |
| 213 | 251 |
| 214 | 252 |
| 215 class CodeSourceMapReader : public ValueObject { | 253 class CodeSourceMapReader : public ValueObject { |
| 216 public: | 254 public: |
| 217 CodeSourceMapReader(const CodeSourceMap& map, | 255 CodeSourceMapReader(const CodeSourceMap& map, |
| 218 const Array& functions, | 256 const Array& functions, |
| 219 const Function& root) | 257 const Function& root) |
| 220 : map_(map), functions_(functions), root_(root) {} | 258 : map_(map), functions_(functions), root_(root) {} |
| 221 | 259 |
| 222 void GetInlinedFunctionsAt(int32_t pc_offset, | 260 void GetInlinedFunctionsAt(int32_t pc_offset, |
| 223 GrowableArray<const Function*>* function_stack, | 261 GrowableArray<const Function*>* function_stack, |
| 224 GrowableArray<TokenPosition>* token_positions); | 262 GrowableArray<TokenPosition>* token_positions); |
| 225 NOT_IN_PRODUCT(void PrintJSONInlineIntervals(JSONObject* jsobj)); | 263 NOT_IN_PRODUCT(void PrintJSONInlineIntervals(JSONObject* jsobj)); |
| 226 void DumpInlineIntervals(uword start); | 264 void DumpInlineIntervals(uword start); |
| 227 void DumpSourcePositions(uword start); | 265 void DumpSourcePositions(uword start); |
| 228 | 266 |
| 229 private: | 267 private: |
| 230 const CodeSourceMap& map_; | 268 const CodeSourceMap& map_; |
| 231 const Array& functions_; | 269 const Array& functions_; |
| 232 const Function& root_; | 270 const Function& root_; |
| 233 | 271 |
| 234 DISALLOW_COPY_AND_ASSIGN(CodeSourceMapReader); | 272 DISALLOW_COPY_AND_ASSIGN(CodeSourceMapReader); |
| 235 }; | 273 }; |
| 236 | 274 |
| 237 } // namespace dart | 275 } // namespace dart |
| 238 | 276 |
| 239 #endif // RUNTIME_VM_CODE_DESCRIPTORS_H_ | 277 #endif // RUNTIME_VM_CODE_DESCRIPTORS_H_ |
| OLD | NEW |