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

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

Issue 2686813006: Reapply "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 | « runtime/vm/code_descriptors.h ('k') | runtime/vm/debugger.cc » ('j') | no next file with comments »
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 #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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 Zone* zone = Thread::Current()->zone(); 121 Zone* zone = Thread::Current()->zone();
122 return zone->Realloc<uint8_t>(ptr, old_size, new_size); 122 return zone->Realloc<uint8_t>(ptr, old_size, new_size);
123 } 123 }
124 124
125 125
126 const TokenPosition CodeSourceMapBuilder::kInitialPosition = 126 const TokenPosition CodeSourceMapBuilder::kInitialPosition =
127 TokenPosition::kDartCodePrologue; 127 TokenPosition::kDartCodePrologue;
128 128
129 129
130 CodeSourceMapBuilder::CodeSourceMapBuilder( 130 CodeSourceMapBuilder::CodeSourceMapBuilder(
131 bool stack_traces_only,
131 const GrowableArray<intptr_t>& caller_inline_id, 132 const GrowableArray<intptr_t>& caller_inline_id,
132 const GrowableArray<TokenPosition>& inline_id_to_token_pos, 133 const GrowableArray<TokenPosition>& inline_id_to_token_pos,
133 const GrowableArray<const Function*>& inline_id_to_function) 134 const GrowableArray<const Function*>& inline_id_to_function)
134 : pc_offset_(0), 135 : buffered_pc_offset_(0),
135 advance_pc_peephole_(0), 136 buffered_inline_id_stack_(),
136 inline_id_stack_(), 137 buffered_token_pos_stack_(),
137 token_pos_stack_(), 138 written_pc_offset_(0),
139 written_inline_id_stack_(),
140 written_token_pos_stack_(),
138 caller_inline_id_(caller_inline_id), 141 caller_inline_id_(caller_inline_id),
139 inline_id_to_token_pos_(inline_id_to_token_pos), 142 inline_id_to_token_pos_(inline_id_to_token_pos),
140 inline_id_to_function_(inline_id_to_function), 143 inline_id_to_function_(inline_id_to_function),
141 buffer_(NULL), 144 buffer_(NULL),
142 stream_(&buffer_, zone_allocator, 64) { 145 stream_(&buffer_, zone_allocator, 64),
143 inline_id_stack_.Add(0); 146 stack_traces_only_(stack_traces_only) {
144 token_pos_stack_.Add(TokenPosition::kDartCodePrologue); 147 buffered_inline_id_stack_.Add(0);
148 buffered_token_pos_stack_.Add(kInitialPosition);
149 written_inline_id_stack_.Add(0);
150 written_token_pos_stack_.Add(kInitialPosition);
151 }
152
153
154 void CodeSourceMapBuilder::FlushBuffer() {
155 FlushBufferStack();
156 FlushBufferPosition();
157 FlushBufferPC();
158 }
159
160
161 void CodeSourceMapBuilder::FlushBufferStack() {
162 for (intptr_t i = buffered_inline_id_stack_.length() - 1; i >= 0; i--) {
163 intptr_t buffered_id = buffered_inline_id_stack_[i];
164 if (i < written_inline_id_stack_.length()) {
165 intptr_t written_id = written_inline_id_stack_[i];
166 if (buffered_id == written_id) {
167 // i is the top-most position where the buffered and written stack
168 // match.
169 while (written_inline_id_stack_.length() > i + 1) {
170 WritePop();
171 }
172 for (intptr_t j = i + 1; j < buffered_inline_id_stack_.length(); j++) {
173 TokenPosition buffered_pos = buffered_token_pos_stack_[j - 1];
174 TokenPosition written_pos = written_token_pos_stack_[j - 1];
175 if (buffered_pos != written_pos) {
176 WriteChangePosition(buffered_pos);
177 }
178 WritePush(buffered_inline_id_stack_[j]);
179 }
180 return;
181 }
182 }
183 }
184 UNREACHABLE();
185 }
186
187
188 void CodeSourceMapBuilder::FlushBufferPosition() {
189 ASSERT(buffered_token_pos_stack_.length() ==
190 written_token_pos_stack_.length());
191
192 intptr_t top = buffered_token_pos_stack_.length() - 1;
193 TokenPosition buffered_pos = buffered_token_pos_stack_[top];
194 TokenPosition written_pos = written_token_pos_stack_[top];
195 if (buffered_pos != written_pos) {
196 WriteChangePosition(buffered_pos);
197 }
198 }
199
200
201 void CodeSourceMapBuilder::FlushBufferPC() {
202 if (buffered_pc_offset_ != written_pc_offset_) {
203 WriteAdvancePC(buffered_pc_offset_ - written_pc_offset_);
204 }
145 } 205 }
146 206
147 207
148 void CodeSourceMapBuilder::StartInliningInterval(int32_t pc_offset, 208 void CodeSourceMapBuilder::StartInliningInterval(int32_t pc_offset,
149 intptr_t inline_id) { 209 intptr_t inline_id) {
150 if (inline_id_stack_.Last() == inline_id) { 210 if (buffered_inline_id_stack_.Last() == inline_id) {
151 // No change in function stack. 211 // No change in function stack.
152 return; 212 return;
153 } 213 }
154 if (inline_id == -1) { 214 if (inline_id == -1) {
155 // Basic blocking missing an inline_id. 215 // Basic blocking missing an inline_id.
156 return; 216 return;
157 } 217 }
158 218
219 if (!stack_traces_only_) {
220 FlushBuffer();
221 }
222
159 // Find a minimal set of pops and pushes to bring us to the new function 223 // Find a minimal set of pops and pushes to bring us to the new function
160 // stack. 224 // stack.
161 225
162 // Pop to a common ancestor. 226 // Pop to a common ancestor.
163 intptr_t common_parent = inline_id; 227 intptr_t common_parent = inline_id;
164 while (!IsOnStack(common_parent)) { 228 while (!IsOnBufferedStack(common_parent)) {
165 common_parent = caller_inline_id_[common_parent]; 229 common_parent = caller_inline_id_[common_parent];
166 } 230 }
167 while (inline_id_stack_.Last() != common_parent) { 231 while (buffered_inline_id_stack_.Last() != common_parent) {
168 EmitPop(); 232 BufferPop();
169 inline_id_stack_.RemoveLast();
170 token_pos_stack_.RemoveLast();
171 } 233 }
172 234
173 // Push to the new top-of-stack function. 235 // Push to the new top-of-stack function.
174 GrowableArray<intptr_t> to_push; 236 GrowableArray<intptr_t> to_push;
175 intptr_t id = inline_id; 237 intptr_t id = inline_id;
176 while (id != common_parent) { 238 while (id != common_parent) {
177 to_push.Add(id); 239 to_push.Add(id);
178 id = caller_inline_id_[id]; 240 id = caller_inline_id_[id];
179 } 241 }
180 for (intptr_t i = to_push.length() - 1; i >= 0; i--) { 242 for (intptr_t i = to_push.length() - 1; i >= 0; i--) {
181 intptr_t push_id = to_push[i]; 243 intptr_t callee_id = to_push[i];
182 TokenPosition call_token; 244 TokenPosition call_token;
183 if (push_id != 0) { 245 if (callee_id != 0) {
184 // TODO(rmacnak): Should make this array line up with the others. 246 // TODO(rmacnak): Should make this array line up with the others.
185 call_token = inline_id_to_token_pos_[push_id - 1]; 247 call_token = inline_id_to_token_pos_[callee_id - 1];
248 } else {
249 UNREACHABLE();
186 } 250 }
187 251
188 // Report caller as at the position of the call. 252 // Report caller as at the position of the call.
189 if (call_token != token_pos_stack_.Last()) { 253 BufferChangePosition(call_token);
190 EmitPosition(call_token);
191 token_pos_stack_[token_pos_stack_.length() - 1] = call_token;
192 }
193 254
194 // Push the callee. 255 BufferPush(callee_id);
195 EmitPush(push_id);
196 inline_id_stack_.Add(push_id);
197 token_pos_stack_.Add(TokenPosition::kDartCodePrologue);
198 } 256 }
199 } 257 }
200 258
201 259
202 void CodeSourceMapBuilder::BeginCodeSourceRange(int32_t pc_offset) {} 260 void CodeSourceMapBuilder::BeginCodeSourceRange(int32_t pc_offset) {}
203 261
204 262
205 void CodeSourceMapBuilder::EndCodeSourceRange(int32_t pc_offset, 263 void CodeSourceMapBuilder::EndCodeSourceRange(int32_t pc_offset,
206 TokenPosition pos) { 264 TokenPosition pos) {
207 if (pc_offset == pc_offset_) { 265 if (pc_offset == buffered_pc_offset_) {
208 return; // Empty intermediate instruction. 266 return; // Empty intermediate instruction.
209 } 267 }
210 if (pos != token_pos_stack_.Last()) { 268 if (pos != buffered_token_pos_stack_.Last()) {
211 EmitPosition(pos); 269 if (!stack_traces_only_) {
212 token_pos_stack_[token_pos_stack_.length() - 1] = pos; 270 FlushBuffer();
271 }
272 BufferChangePosition(pos);
213 } 273 }
214 EmitAdvancePC(pc_offset - pc_offset_); 274 BufferAdvancePC(pc_offset - buffered_pc_offset_);
215 pc_offset_ = pc_offset;
216 } 275 }
217 276
218 277
278 void CodeSourceMapBuilder::NoteDescriptor(RawPcDescriptors::Kind kind,
279 int32_t pc_offset,
280 TokenPosition pos) {
281 const uint8_t kCanThrow =
282 RawPcDescriptors::kIcCall | RawPcDescriptors::kUnoptStaticCall |
283 RawPcDescriptors::kRuntimeCall | RawPcDescriptors::kOther;
284 if (stack_traces_only_ && ((kind & kCanThrow) != 0)) {
285 BufferChangePosition(pos);
286 BufferAdvancePC(pc_offset - buffered_pc_offset_);
287 FlushBuffer();
288 }
289 }
290
291
219 RawArray* CodeSourceMapBuilder::InliningIdToFunction() { 292 RawArray* CodeSourceMapBuilder::InliningIdToFunction() {
220 if (inline_id_to_function_.length() <= 1) { 293 if (inline_id_to_function_.length() <= 1) {
221 // Not optimizing, or optimizing and nothing inlined. 294 // Not optimizing, or optimizing and nothing inlined.
222 return Object::empty_array().raw(); 295 return Object::empty_array().raw();
223 } 296 }
224 const Array& res = 297 const Array& res =
225 Array::Handle(Array::New(inline_id_to_function_.length(), Heap::kOld)); 298 Array::Handle(Array::New(inline_id_to_function_.length(), Heap::kOld));
226 for (intptr_t i = 0; i < inline_id_to_function_.length(); i++) { 299 for (intptr_t i = 0; i < inline_id_to_function_.length(); i++) {
227 res.SetAt(i, *inline_id_to_function_[i]); 300 res.SetAt(i, *inline_id_to_function_[i]);
228 } 301 }
229 return res.raw(); 302 return res.raw();
230 } 303 }
231 304
232 305
233 RawCodeSourceMap* CodeSourceMapBuilder::Finalize() { 306 RawCodeSourceMap* CodeSourceMapBuilder::Finalize() {
234 FlushPeephole(); 307 if (!stack_traces_only_) {
308 FlushBuffer();
309 }
235 intptr_t length = stream_.bytes_written(); 310 intptr_t length = stream_.bytes_written();
236 const CodeSourceMap& map = CodeSourceMap::Handle(CodeSourceMap::New(length)); 311 const CodeSourceMap& map = CodeSourceMap::Handle(CodeSourceMap::New(length));
237 NoSafepointScope no_safepoint; 312 NoSafepointScope no_safepoint;
238 memmove(map.Data(), buffer_, length); 313 memmove(map.Data(), buffer_, length);
239 return map.raw(); 314 return map.raw();
240 } 315 }
241 316
242 317
243 void CodeSourceMapReader::GetInlinedFunctionsAt( 318 void CodeSourceMapReader::GetInlinedFunctionsAt(
244 int32_t pc_offset, 319 int32_t pc_offset,
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 break; 523 break;
449 } 524 }
450 default: 525 default:
451 UNREACHABLE(); 526 UNREACHABLE();
452 } 527 }
453 } 528 }
454 THR_Print("}\n"); 529 THR_Print("}\n");
455 } 530 }
456 531
457 } // namespace dart 532 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/code_descriptors.h ('k') | runtime/vm/debugger.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698