Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Side by Side Diff: runtime/vm/code_descriptors.h

Issue 2684763002: Use CodeSourceMap for stack traces (still JIT only). (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | runtime/vm/code_descriptors.cc » ('j') | runtime/vm/object.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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_
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/code_descriptors.cc » ('j') | runtime/vm/object.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698