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

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

Issue 14711013: Implement backtracing and toggling of execution tracing in ARM simulator. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/stack_frame.h ('k') | no next file » | 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/stack_frame.h" 5 #include "vm/stack_frame.h"
6 6
7 #include "vm/assembler.h" 7 #include "vm/assembler.h"
8 #include "vm/deopt_instructions.h" 8 #include "vm/deopt_instructions.h"
9 #include "vm/isolate.h" 9 #include "vm/isolate.h"
10 #include "vm/object.h" 10 #include "vm/object.h"
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 uword exit_marker = current->top_exit_frame_info(); 208 uword exit_marker = current->top_exit_frame_info();
209 frames_.fp_ = exit_marker; 209 frames_.fp_ = exit_marker;
210 } 210 }
211 211
212 212
213 void StackFrameIterator::SetupNextExitFrameData() { 213 void StackFrameIterator::SetupNextExitFrameData() {
214 uword exit_address = entry_.fp() + (kExitLinkSlotFromEntryFp * kWordSize); 214 uword exit_address = entry_.fp() + (kExitLinkSlotFromEntryFp * kWordSize);
215 uword exit_marker = *reinterpret_cast<uword*>(exit_address); 215 uword exit_marker = *reinterpret_cast<uword*>(exit_address);
216 frames_.fp_ = exit_marker; 216 frames_.fp_ = exit_marker;
217 frames_.sp_ = 0; 217 frames_.sp_ = 0;
218 frames_.pc_ = 0;
218 } 219 }
219 220
220 221
221 StackFrameIterator::StackFrameIterator(bool validate) 222 StackFrameIterator::StackFrameIterator(bool validate)
222 : validate_(validate), entry_(), exit_(), current_frame_(NULL) { 223 : validate_(validate), entry_(), exit_(), current_frame_(NULL) {
223 SetupLastExitFrameData(); // Setup data for last exit frame. 224 SetupLastExitFrameData(); // Setup data for last exit frame.
224 } 225 }
225 226
227
226 StackFrameIterator::StackFrameIterator(uword last_fp, bool validate) 228 StackFrameIterator::StackFrameIterator(uword last_fp, bool validate)
227 : validate_(validate), entry_(), exit_(), current_frame_(NULL) { 229 : validate_(validate), entry_(), exit_(), current_frame_(NULL) {
228 frames_.fp_ = last_fp; 230 frames_.fp_ = last_fp;
231 frames_.sp_ = 0;
232 frames_.pc_ = 0;
233 }
234
235
236 StackFrameIterator::StackFrameIterator(uword fp, uword sp, uword pc,
237 bool validate)
238 : validate_(validate), entry_(), exit_(), current_frame_(NULL) {
239 frames_.fp_ = fp;
240 frames_.sp_ = sp;
241 frames_.pc_ = pc;
229 } 242 }
230 243
231 244
232 StackFrame* StackFrameIterator::NextFrame() { 245 StackFrame* StackFrameIterator::NextFrame() {
233 // When we are at the start of iteration after having created an 246 // When we are at the start of iteration after having created an
234 // iterator object current_frame_ will be NULL as we haven't seen 247 // iterator object, current_frame_ will be NULL as we haven't seen
235 // any frames yet. At this point if NextFrame is called it tries 248 // any frames yet (unless we start iterating in the simulator from a given
249 // triplet of fp, sp, and pc). At this point, if NextFrame is called, it tries
236 // to set up the next exit frame by reading the top_exit_frame_info 250 // to set up the next exit frame by reading the top_exit_frame_info
237 // from the isolate. If we do not have any dart invocations yet 251 // from the isolate. If we do not have any dart invocations yet,
238 // top_exit_frame_info will be 0 and so we would return NULL. 252 // top_exit_frame_info will be 0 and so we would return NULL.
239 253
240 // current_frame_ will also be NULL, when we are at the end of having 254 // current_frame_ will also be NULL, when we are at the end of having
241 // iterated through all the frames. if NextFrame is called at this 255 // iterated through all the frames. If NextFrame is called at this
242 // point we will try and set up the next exit frame but since we are 256 // point, we will try and set up the next exit frame, but since we are
243 // at the end of the iteration fp_ will be 0 and we would return NULL. 257 // at the end of the iteration, fp_ will be 0 and we would return NULL.
244 if (current_frame_ == NULL) { 258 if (current_frame_ == NULL) {
245 if (!HasNextFrame()) { 259 if (!HasNextFrame()) {
246 return NULL; 260 return NULL;
247 } 261 }
248 current_frame_ = NextExitFrame(); 262 if (frames_.pc_ == 0) {
263 // Iteration starts from an exit frame given by its fp.
264 current_frame_ = NextExitFrame();
265 } else if (*(reinterpret_cast<uword*>(
266 frames_.fp_ + (kSavedCallerFpSlotFromFp * kWordSize))) == 0) {
267 // Iteration starts from an entry frame given by its fp, sp, and pc.
268 current_frame_ = NextEntryFrame();
269 } else {
270 // Iteration starts from a Dart or stub frame given by its fp, sp, and pc.
271 current_frame_ = frames_.NextFrame(validate_);
272 }
249 return current_frame_; 273 return current_frame_;
250 } 274 }
251 ASSERT((validate_ == kDontValidateFrames) || current_frame_->IsValid()); 275 ASSERT((validate_ == kDontValidateFrames) || current_frame_->IsValid());
252 if (current_frame_->IsEntryFrame()) { 276 if (current_frame_->IsEntryFrame()) {
253 if (HasNextFrame()) { // We have another chained block. 277 if (HasNextFrame()) { // We have another chained block.
254 current_frame_ = NextExitFrame(); 278 current_frame_ = NextExitFrame();
255 return current_frame_; 279 return current_frame_;
256 } 280 }
257 current_frame_ = NULL; // No more frames. 281 current_frame_ = NULL; // No more frames.
258 return current_frame_; 282 return current_frame_;
(...skipping 10 matching lines...) Expand all
269 return current_frame_; 293 return current_frame_;
270 } 294 }
271 295
272 296
273 StackFrame* StackFrameIterator::FrameSetIterator::NextFrame(bool validate) { 297 StackFrame* StackFrameIterator::FrameSetIterator::NextFrame(bool validate) {
274 StackFrame* frame; 298 StackFrame* frame;
275 ASSERT(HasNext()); 299 ASSERT(HasNext());
276 frame = &stack_frame_; 300 frame = &stack_frame_;
277 frame->sp_ = sp_; 301 frame->sp_ = sp_;
278 frame->fp_ = fp_; 302 frame->fp_ = fp_;
303 frame->pc_ = pc_;
279 sp_ = frame->GetCallerSp(); 304 sp_ = frame->GetCallerSp();
280 fp_ = frame->GetCallerFp(); 305 fp_ = frame->GetCallerFp();
306 pc_ = frame->GetCallerPc();
281 ASSERT((validate == kDontValidateFrames) || frame->IsValid()); 307 ASSERT((validate == kDontValidateFrames) || frame->IsValid());
282 return frame; 308 return frame;
283 } 309 }
284 310
285 311
286 ExitFrame* StackFrameIterator::NextExitFrame() { 312 ExitFrame* StackFrameIterator::NextExitFrame() {
287 exit_.sp_ = frames_.sp_; 313 exit_.sp_ = frames_.sp_;
288 exit_.fp_ = frames_.fp_; 314 exit_.fp_ = frames_.fp_;
315 exit_.pc_ = frames_.pc_;
289 frames_.sp_ = exit_.GetCallerSp(); 316 frames_.sp_ = exit_.GetCallerSp();
290 frames_.fp_ = exit_.GetCallerFp(); 317 frames_.fp_ = exit_.GetCallerFp();
318 frames_.pc_ = exit_.GetCallerPc();
291 ASSERT(exit_.IsValid()); 319 ASSERT(exit_.IsValid());
292 return &exit_; 320 return &exit_;
293 } 321 }
294 322
295 323
296 EntryFrame* StackFrameIterator::NextEntryFrame() { 324 EntryFrame* StackFrameIterator::NextEntryFrame() {
297 ASSERT(!frames_.HasNext()); 325 ASSERT(!frames_.HasNext());
298 entry_.sp_ = frames_.sp_; 326 entry_.sp_ = frames_.sp_;
299 entry_.fp_ = frames_.fp_; 327 entry_.fp_ = frames_.fp_;
328 entry_.pc_ = frames_.pc_;
300 SetupNextExitFrameData(); // Setup data for next exit frame in chain. 329 SetupNextExitFrameData(); // Setup data for next exit frame in chain.
301 ASSERT(entry_.IsValid()); 330 ASSERT(entry_.IsValid());
302 return &entry_; 331 return &entry_;
303 } 332 }
304 333
305 334
306 InlinedFunctionsIterator::InlinedFunctionsIterator(StackFrame* frame) 335 InlinedFunctionsIterator::InlinedFunctionsIterator(StackFrame* frame)
307 : index_(0), 336 : index_(0),
308 code_(Code::Handle()), 337 code_(Code::Handle()),
309 deopt_info_(DeoptInfo::Handle()), 338 deopt_info_(DeoptInfo::Handle()),
310 function_(Function::Handle()), 339 function_(Function::Handle()),
311 pc_(0), 340 pc_(0),
312 deopt_instructions_(), 341 deopt_instructions_(),
313 object_table_(Array::Handle()) { 342 object_table_(Array::Handle()) {
314 ASSERT(frame != NULL); 343 ASSERT(frame != NULL);
315 code_ = frame->LookupDartCode(); 344 code_ = frame->LookupDartCode();
316 ASSERT(code_.is_optimized()); 345 ASSERT(code_.is_optimized());
317 intptr_t deopt_reason = kDeoptUnknown; 346 intptr_t deopt_reason = kDeoptUnknown;
318 deopt_info_ = code_.GetDeoptInfoAtPc(frame->pc(), &deopt_reason); 347 deopt_info_ = code_.GetDeoptInfoAtPc(frame->pc(), &deopt_reason);
319 if (deopt_info_.IsNull()) { 348 if (deopt_info_.IsNull()) {
320 // This is the case when a call without deopt info in optimzed code 349 // This is the case when a call without deopt info in optimized code
321 // throws an exception. (e.g. in the parameter copying prologue). 350 // throws an exception. (e.g. in the parameter copying prologue).
322 // In that case there won't be any inlined frames. 351 // In that case there won't be any inlined frames.
323 function_ = code_.function(); 352 function_ = code_.function();
324 pc_ = frame->pc(); 353 pc_ = frame->pc();
325 ASSERT(pc_ != 0); 354 ASSERT(pc_ != 0);
326 } else { 355 } else {
327 // Unpack deopt info into instructions (translate away suffixes). 356 // Unpack deopt info into instructions (translate away suffixes).
328 const Array& deopt_table = Array::Handle(code_.deopt_info_array()); 357 const Array& deopt_table = Array::Handle(code_.deopt_info_array());
329 ASSERT(!deopt_table.IsNull()); 358 ASSERT(!deopt_table.IsNull());
330 deopt_info_.ToInstructions(deopt_table, &deopt_instructions_); 359 deopt_info_.ToInstructions(deopt_table, &deopt_instructions_);
(...skipping 21 matching lines...) Expand all
352 pc_ = DeoptInstr::GetRetAddress(deopt_instr, object_table_, &func); 381 pc_ = DeoptInstr::GetRetAddress(deopt_instr, object_table_, &func);
353 code_ = func.unoptimized_code(); 382 code_ = func.unoptimized_code();
354 function_ = func.raw(); 383 function_ = func.raw();
355 return; 384 return;
356 } 385 }
357 } 386 }
358 SetDone(); 387 SetDone();
359 } 388 }
360 389
361 } // namespace dart 390 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/stack_frame.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698