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

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

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 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/stack_frame.h ('k') | runtime/vm/stack_frame_dbc.h » ('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/stack_frame.h" 5 #include "vm/stack_frame.h"
6 6
7 #include "platform/memory_sanitizer.h" 7 #include "platform/memory_sanitizer.h"
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/deopt_instructions.h" 9 #include "vm/deopt_instructions.h"
10 #include "vm/isolate.h" 10 #include "vm/isolate.h"
11 #include "vm/object.h" 11 #include "vm/object.h"
12 #include "vm/object_store.h" 12 #include "vm/object_store.h"
13 #include "vm/os.h" 13 #include "vm/os.h"
14 #include "vm/parser.h" 14 #include "vm/parser.h"
15 #include "vm/raw_object.h" 15 #include "vm/raw_object.h"
16 #include "vm/reusable_handles.h" 16 #include "vm/reusable_handles.h"
17 #include "vm/stub_code.h" 17 #include "vm/stub_code.h"
18 #include "vm/visitor.h" 18 #include "vm/visitor.h"
19 19
20 namespace dart { 20 namespace dart {
21 21
22
23 bool StackFrame::IsStubFrame() const { 22 bool StackFrame::IsStubFrame() const {
24 ASSERT(!(IsEntryFrame() || IsExitFrame())); 23 ASSERT(!(IsEntryFrame() || IsExitFrame()));
25 #if !defined(HOST_OS_WINDOWS) && !defined(HOST_OS_FUCHSIA) 24 #if !defined(HOST_OS_WINDOWS) && !defined(HOST_OS_FUCHSIA)
26 // On Windows and Fuchsia, the profiler calls this from a separate thread 25 // On Windows and Fuchsia, the profiler calls this from a separate thread
27 // where Thread::Current() is NULL, so we cannot create a NoSafepointScope. 26 // where Thread::Current() is NULL, so we cannot create a NoSafepointScope.
28 NoSafepointScope no_safepoint; 27 NoSafepointScope no_safepoint;
29 #endif 28 #endif
30 RawCode* code = GetCodeObject(); 29 RawCode* code = GetCodeObject();
31 ASSERT(code != Object::null()); 30 ASSERT(code != Object::null());
32 const intptr_t cid = code->ptr()->owner_->GetClassId(); 31 const intptr_t cid = code->ptr()->owner_->GetClassId();
33 ASSERT(cid == kNullCid || cid == kClassCid || cid == kFunctionCid); 32 ASSERT(cid == kNullCid || cid == kClassCid || cid == kFunctionCid);
34 return cid == kNullCid || cid == kClassCid; 33 return cid == kNullCid || cid == kClassCid;
35 } 34 }
36 35
37
38 const char* StackFrame::ToCString() const { 36 const char* StackFrame::ToCString() const {
39 ASSERT(thread_ == Thread::Current()); 37 ASSERT(thread_ == Thread::Current());
40 Zone* zone = Thread::Current()->zone(); 38 Zone* zone = Thread::Current()->zone();
41 if (IsDartFrame()) { 39 if (IsDartFrame()) {
42 const Code& code = Code::Handle(zone, LookupDartCode()); 40 const Code& code = Code::Handle(zone, LookupDartCode());
43 ASSERT(!code.IsNull()); 41 ASSERT(!code.IsNull());
44 const Object& owner = Object::Handle(zone, code.owner()); 42 const Object& owner = Object::Handle(zone, code.owner());
45 ASSERT(!owner.IsNull()); 43 ASSERT(!owner.IsNull());
46 if (owner.IsFunction()) { 44 if (owner.IsFunction()) {
47 const char* opt = code.is_optimized() ? "*" : ""; 45 const char* opt = code.is_optimized() ? "*" : "";
48 const Function& function = Function::Cast(owner); 46 const Function& function = Function::Cast(owner);
49 return zone->PrintToString( 47 return zone->PrintToString(
50 "[%-8s : sp(%#" Px ") fp(%#" Px ") pc(%#" Px ") %s%s ]", GetName(), 48 "[%-8s : sp(%#" Px ") fp(%#" Px ") pc(%#" Px ") %s%s ]", GetName(),
51 sp(), fp(), pc(), opt, function.ToFullyQualifiedCString()); 49 sp(), fp(), pc(), opt, function.ToFullyQualifiedCString());
52 } else { 50 } else {
53 return zone->PrintToString( 51 return zone->PrintToString(
54 "[%-8s : sp(%#" Px ") fp(%#" Px ") pc(%#" Px ") %s ]", GetName(), 52 "[%-8s : sp(%#" Px ") fp(%#" Px ") pc(%#" Px ") %s ]", GetName(),
55 sp(), fp(), pc(), owner.ToCString()); 53 sp(), fp(), pc(), owner.ToCString());
56 } 54 }
57 } else { 55 } else {
58 return zone->PrintToString("[%-8s : sp(%#" Px ") fp(%#" Px ") pc(%#" Px 56 return zone->PrintToString("[%-8s : sp(%#" Px ") fp(%#" Px ") pc(%#" Px
59 ")]", 57 ")]",
60 GetName(), sp(), fp(), pc()); 58 GetName(), sp(), fp(), pc());
61 } 59 }
62 } 60 }
63 61
64
65 void ExitFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { 62 void ExitFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) {
66 // There are no objects to visit in this frame. 63 // There are no objects to visit in this frame.
67 } 64 }
68 65
69
70 void EntryFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { 66 void EntryFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) {
71 // Visit objects between SP and (FP - callee_save_area). 67 // Visit objects between SP and (FP - callee_save_area).
72 ASSERT(visitor != NULL); 68 ASSERT(visitor != NULL);
73 #if !defined(TARGET_ARCH_DBC) 69 #if !defined(TARGET_ARCH_DBC)
74 RawObject** first = reinterpret_cast<RawObject**>(sp()); 70 RawObject** first = reinterpret_cast<RawObject**>(sp());
75 RawObject** last = reinterpret_cast<RawObject**>( 71 RawObject** last = reinterpret_cast<RawObject**>(
76 fp() + (kExitLinkSlotFromEntryFp - 1) * kWordSize); 72 fp() + (kExitLinkSlotFromEntryFp - 1) * kWordSize);
77 visitor->VisitPointers(first, last); 73 visitor->VisitPointers(first, last);
78 #else 74 #else
79 // On DBC stack is growing upwards which implies fp() <= sp(). 75 // On DBC stack is growing upwards which implies fp() <= sp().
80 RawObject** first = reinterpret_cast<RawObject**>(fp()); 76 RawObject** first = reinterpret_cast<RawObject**>(fp());
81 RawObject** last = reinterpret_cast<RawObject**>(sp()); 77 RawObject** last = reinterpret_cast<RawObject**>(sp());
82 visitor->VisitPointers(first, last); 78 visitor->VisitPointers(first, last);
83 #endif 79 #endif
84 } 80 }
85 81
86
87 void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { 82 void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) {
88 ASSERT(visitor != NULL); 83 ASSERT(visitor != NULL);
89 // NOTE: This code runs while GC is in progress and runs within 84 // NOTE: This code runs while GC is in progress and runs within
90 // a NoHandleScope block. Hence it is not ok to use regular Zone or 85 // a NoHandleScope block. Hence it is not ok to use regular Zone or
91 // Scope handles. We use direct stack handles, the raw pointers in 86 // Scope handles. We use direct stack handles, the raw pointers in
92 // these handles are not traversed. The use of handles is mainly to 87 // these handles are not traversed. The use of handles is mainly to
93 // be able to reuse the handle based code and avoid having to add 88 // be able to reuse the handle based code and avoid having to add
94 // helper functions to the raw object interface. 89 // helper functions to the raw object interface.
95 NoSafepointScope no_safepoint; 90 NoSafepointScope no_safepoint;
96 Code code; 91 Code code;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 #else 192 #else
198 // On DBC stack grows upwards: fp() <= sp(). 193 // On DBC stack grows upwards: fp() <= sp().
199 RawObject** first = reinterpret_cast<RawObject**>( 194 RawObject** first = reinterpret_cast<RawObject**>(
200 fp() + (kFirstObjectSlotFromFp * kWordSize)); 195 fp() + (kFirstObjectSlotFromFp * kWordSize));
201 RawObject** last = reinterpret_cast<RawObject**>(sp()); 196 RawObject** last = reinterpret_cast<RawObject**>(sp());
202 #endif // !defined(TARGET_ARCH_DBC) 197 #endif // !defined(TARGET_ARCH_DBC)
203 198
204 visitor->VisitPointers(first, last); 199 visitor->VisitPointers(first, last);
205 } 200 }
206 201
207
208 RawFunction* StackFrame::LookupDartFunction() const { 202 RawFunction* StackFrame::LookupDartFunction() const {
209 const Code& code = Code::Handle(LookupDartCode()); 203 const Code& code = Code::Handle(LookupDartCode());
210 if (!code.IsNull()) { 204 if (!code.IsNull()) {
211 return code.function(); 205 return code.function();
212 } 206 }
213 return Function::null(); 207 return Function::null();
214 } 208 }
215 209
216
217 RawCode* StackFrame::LookupDartCode() const { 210 RawCode* StackFrame::LookupDartCode() const {
218 // We add a no gc scope to ensure that the code below does not trigger 211 // We add a no gc scope to ensure that the code below does not trigger
219 // a GC as we are handling raw object references here. It is possible 212 // a GC as we are handling raw object references here. It is possible
220 // that the code is called while a GC is in progress, that is ok. 213 // that the code is called while a GC is in progress, that is ok.
221 #if !defined(HOST_OS_WINDOWS) && !defined(HOST_OS_FUCHSIA) 214 #if !defined(HOST_OS_WINDOWS) && !defined(HOST_OS_FUCHSIA)
222 // On Windows and Fuchsia, the profiler calls this from a separate thread 215 // On Windows and Fuchsia, the profiler calls this from a separate thread
223 // where Thread::Current() is NULL, so we cannot create a NoSafepointScope. 216 // where Thread::Current() is NULL, so we cannot create a NoSafepointScope.
224 NoSafepointScope no_safepoint; 217 NoSafepointScope no_safepoint;
225 #endif 218 #endif
226 RawCode* code = GetCodeObject(); 219 RawCode* code = GetCodeObject();
227 if ((code != Code::null()) && 220 if ((code != Code::null()) &&
228 (code->ptr()->owner_->GetClassId() == kFunctionCid)) { 221 (code->ptr()->owner_->GetClassId() == kFunctionCid)) {
229 return code; 222 return code;
230 } 223 }
231 return Code::null(); 224 return Code::null();
232 } 225 }
233 226
234
235 RawCode* StackFrame::GetCodeObject() const { 227 RawCode* StackFrame::GetCodeObject() const {
236 const uword pc_marker = 228 const uword pc_marker =
237 *(reinterpret_cast<uword*>(fp() + (kPcMarkerSlotFromFp * kWordSize))); 229 *(reinterpret_cast<uword*>(fp() + (kPcMarkerSlotFromFp * kWordSize)));
238 ASSERT(pc_marker != 0); 230 ASSERT(pc_marker != 0);
239 ASSERT(reinterpret_cast<RawObject*>(pc_marker)->GetClassId() == kCodeCid || 231 ASSERT(reinterpret_cast<RawObject*>(pc_marker)->GetClassId() == kCodeCid ||
240 reinterpret_cast<RawObject*>(pc_marker) == Object::null()); 232 reinterpret_cast<RawObject*>(pc_marker) == Object::null());
241 return reinterpret_cast<RawCode*>(pc_marker); 233 return reinterpret_cast<RawCode*>(pc_marker);
242 } 234 }
243 235
244
245 bool StackFrame::FindExceptionHandler(Thread* thread, 236 bool StackFrame::FindExceptionHandler(Thread* thread,
246 uword* handler_pc, 237 uword* handler_pc,
247 bool* needs_stacktrace, 238 bool* needs_stacktrace,
248 bool* has_catch_all, 239 bool* has_catch_all,
249 bool* is_optimized) const { 240 bool* is_optimized) const {
250 REUSABLE_CODE_HANDLESCOPE(thread); 241 REUSABLE_CODE_HANDLESCOPE(thread);
251 Code& code = reused_code_handle.Handle(); 242 Code& code = reused_code_handle.Handle();
252 code = LookupDartCode(); 243 code = LookupDartCode();
253 if (code.IsNull()) { 244 if (code.IsNull()) {
254 return false; // Stub frames do not have exception handlers. 245 return false; // Stub frames do not have exception handlers.
(...skipping 29 matching lines...) Expand all
284 *handler_pc = code.PayloadStart() + handler_info.handler_pc_offset; 275 *handler_pc = code.PayloadStart() + handler_info.handler_pc_offset;
285 *needs_stacktrace = handler_info.needs_stacktrace; 276 *needs_stacktrace = handler_info.needs_stacktrace;
286 *has_catch_all = handler_info.has_catch_all; 277 *has_catch_all = handler_info.has_catch_all;
287 cache->Insert(pc(), handler_info); 278 cache->Insert(pc(), handler_info);
288 return true; 279 return true;
289 } 280 }
290 } 281 }
291 return false; 282 return false;
292 } 283 }
293 284
294
295 TokenPosition StackFrame::GetTokenPos() const { 285 TokenPosition StackFrame::GetTokenPos() const {
296 const Code& code = Code::Handle(LookupDartCode()); 286 const Code& code = Code::Handle(LookupDartCode());
297 if (code.IsNull()) { 287 if (code.IsNull()) {
298 return TokenPosition::kNoSource; // Stub frames do not have token_pos. 288 return TokenPosition::kNoSource; // Stub frames do not have token_pos.
299 } 289 }
300 uword pc_offset = pc() - code.PayloadStart(); 290 uword pc_offset = pc() - code.PayloadStart();
301 const PcDescriptors& descriptors = 291 const PcDescriptors& descriptors =
302 PcDescriptors::Handle(code.pc_descriptors()); 292 PcDescriptors::Handle(code.pc_descriptors());
303 ASSERT(!descriptors.IsNull()); 293 ASSERT(!descriptors.IsNull());
304 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind); 294 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
305 while (iter.MoveNext()) { 295 while (iter.MoveNext()) {
306 if (iter.PcOffset() == pc_offset) { 296 if (iter.PcOffset() == pc_offset) {
307 return TokenPosition(iter.TokenPos()); 297 return TokenPosition(iter.TokenPos());
308 } 298 }
309 } 299 }
310 return TokenPosition::kNoSource; 300 return TokenPosition::kNoSource;
311 } 301 }
312 302
313
314 bool StackFrame::IsValid() const { 303 bool StackFrame::IsValid() const {
315 if (IsEntryFrame() || IsExitFrame() || IsStubFrame()) { 304 if (IsEntryFrame() || IsExitFrame() || IsStubFrame()) {
316 return true; 305 return true;
317 } 306 }
318 return (LookupDartCode() != Code::null()); 307 return (LookupDartCode() != Code::null());
319 } 308 }
320 309
321
322 void StackFrameIterator::SetupLastExitFrameData() { 310 void StackFrameIterator::SetupLastExitFrameData() {
323 ASSERT(thread_ != NULL); 311 ASSERT(thread_ != NULL);
324 uword exit_marker = thread_->top_exit_frame_info(); 312 uword exit_marker = thread_->top_exit_frame_info();
325 frames_.fp_ = exit_marker; 313 frames_.fp_ = exit_marker;
326 } 314 }
327 315
328
329 void StackFrameIterator::SetupNextExitFrameData() { 316 void StackFrameIterator::SetupNextExitFrameData() {
330 uword exit_address = entry_.fp() + (kExitLinkSlotFromEntryFp * kWordSize); 317 uword exit_address = entry_.fp() + (kExitLinkSlotFromEntryFp * kWordSize);
331 uword exit_marker = *reinterpret_cast<uword*>(exit_address); 318 uword exit_marker = *reinterpret_cast<uword*>(exit_address);
332 frames_.fp_ = exit_marker; 319 frames_.fp_ = exit_marker;
333 frames_.sp_ = 0; 320 frames_.sp_ = 0;
334 frames_.pc_ = 0; 321 frames_.pc_ = 0;
335 } 322 }
336 323
337
338 // Tell MemorySanitizer that generated code initializes part of the stack. 324 // Tell MemorySanitizer that generated code initializes part of the stack.
339 // TODO(koda): Limit to frames that are actually written by generated code. 325 // TODO(koda): Limit to frames that are actually written by generated code.
340 static void UnpoisonStack(uword fp) { 326 static void UnpoisonStack(uword fp) {
341 ASSERT(fp != 0); 327 ASSERT(fp != 0);
342 uword size = OSThread::GetSpecifiedStackSize(); 328 uword size = OSThread::GetSpecifiedStackSize();
343 MSAN_UNPOISON(reinterpret_cast<void*>(fp - size), 2 * size); 329 MSAN_UNPOISON(reinterpret_cast<void*>(fp - size), 2 * size);
344 } 330 }
345 331
346
347 StackFrameIterator::StackFrameIterator(ValidationPolicy validation_policy, 332 StackFrameIterator::StackFrameIterator(ValidationPolicy validation_policy,
348 Thread* thread, 333 Thread* thread,
349 CrossThreadPolicy cross_thread_policy) 334 CrossThreadPolicy cross_thread_policy)
350 : validate_(validation_policy == kValidateFrames), 335 : validate_(validation_policy == kValidateFrames),
351 entry_(thread), 336 entry_(thread),
352 exit_(thread), 337 exit_(thread),
353 frames_(thread), 338 frames_(thread),
354 current_frame_(NULL), 339 current_frame_(NULL),
355 thread_(thread) { 340 thread_(thread) {
356 ASSERT(cross_thread_policy == kAllowCrossThreadIteration || 341 ASSERT(cross_thread_policy == kAllowCrossThreadIteration ||
357 thread_ == Thread::Current()); 342 thread_ == Thread::Current());
358 SetupLastExitFrameData(); // Setup data for last exit frame. 343 SetupLastExitFrameData(); // Setup data for last exit frame.
359 } 344 }
360 345
361
362 StackFrameIterator::StackFrameIterator(uword last_fp, 346 StackFrameIterator::StackFrameIterator(uword last_fp,
363 ValidationPolicy validation_policy, 347 ValidationPolicy validation_policy,
364 Thread* thread, 348 Thread* thread,
365 CrossThreadPolicy cross_thread_policy) 349 CrossThreadPolicy cross_thread_policy)
366 : validate_(validation_policy == kValidateFrames), 350 : validate_(validation_policy == kValidateFrames),
367 entry_(thread), 351 entry_(thread),
368 exit_(thread), 352 exit_(thread),
369 frames_(thread), 353 frames_(thread),
370 current_frame_(NULL), 354 current_frame_(NULL),
371 thread_(thread) { 355 thread_(thread) {
372 ASSERT(cross_thread_policy == kAllowCrossThreadIteration || 356 ASSERT(cross_thread_policy == kAllowCrossThreadIteration ||
373 thread_ == Thread::Current()); 357 thread_ == Thread::Current());
374 frames_.fp_ = last_fp; 358 frames_.fp_ = last_fp;
375 frames_.sp_ = 0; 359 frames_.sp_ = 0;
376 frames_.pc_ = 0; 360 frames_.pc_ = 0;
377 } 361 }
378 362
379
380 #if !defined(TARGET_ARCH_DBC) 363 #if !defined(TARGET_ARCH_DBC)
381 StackFrameIterator::StackFrameIterator(uword fp, 364 StackFrameIterator::StackFrameIterator(uword fp,
382 uword sp, 365 uword sp,
383 uword pc, 366 uword pc,
384 ValidationPolicy validation_policy, 367 ValidationPolicy validation_policy,
385 Thread* thread, 368 Thread* thread,
386 CrossThreadPolicy cross_thread_policy) 369 CrossThreadPolicy cross_thread_policy)
387 : validate_(validation_policy == kValidateFrames), 370 : validate_(validation_policy == kValidateFrames),
388 entry_(thread), 371 entry_(thread),
389 exit_(thread), 372 exit_(thread),
390 frames_(thread), 373 frames_(thread),
391 current_frame_(NULL), 374 current_frame_(NULL),
392 thread_(thread) { 375 thread_(thread) {
393 ASSERT(cross_thread_policy == kAllowCrossThreadIteration || 376 ASSERT(cross_thread_policy == kAllowCrossThreadIteration ||
394 thread_ == Thread::Current()); 377 thread_ == Thread::Current());
395 frames_.fp_ = fp; 378 frames_.fp_ = fp;
396 frames_.sp_ = sp; 379 frames_.sp_ = sp;
397 frames_.pc_ = pc; 380 frames_.pc_ = pc;
398 } 381 }
399 #endif 382 #endif
400 383
401
402 StackFrame* StackFrameIterator::NextFrame() { 384 StackFrame* StackFrameIterator::NextFrame() {
403 // When we are at the start of iteration after having created an 385 // When we are at the start of iteration after having created an
404 // iterator object, current_frame_ will be NULL as we haven't seen 386 // iterator object, current_frame_ will be NULL as we haven't seen
405 // any frames yet (unless we start iterating in the simulator from a given 387 // any frames yet (unless we start iterating in the simulator from a given
406 // triplet of fp, sp, and pc). At this point, if NextFrame is called, it tries 388 // triplet of fp, sp, and pc). At this point, if NextFrame is called, it tries
407 // to set up the next exit frame by reading the top_exit_frame_info 389 // to set up the next exit frame by reading the top_exit_frame_info
408 // from the isolate. If we do not have any dart invocations yet, 390 // from the isolate. If we do not have any dart invocations yet,
409 // top_exit_frame_info will be 0 and so we would return NULL. 391 // top_exit_frame_info will be 0 and so we would return NULL.
410 392
411 // current_frame_ will also be NULL, when we are at the end of having 393 // current_frame_ will also be NULL, when we are at the end of having
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 current_frame_->IsStubFrame()); 434 current_frame_->IsStubFrame());
453 435
454 // Consume dart/stub frames using StackFrameIterator::FrameSetIterator 436 // Consume dart/stub frames using StackFrameIterator::FrameSetIterator
455 // until we are out of dart/stub frames at which point we return the 437 // until we are out of dart/stub frames at which point we return the
456 // corresponding entry frame for that set of dart/stub frames. 438 // corresponding entry frame for that set of dart/stub frames.
457 current_frame_ = 439 current_frame_ =
458 (frames_.HasNext()) ? frames_.NextFrame(validate_) : NextEntryFrame(); 440 (frames_.HasNext()) ? frames_.NextFrame(validate_) : NextEntryFrame();
459 return current_frame_; 441 return current_frame_;
460 } 442 }
461 443
462
463 StackFrame* StackFrameIterator::FrameSetIterator::NextFrame(bool validate) { 444 StackFrame* StackFrameIterator::FrameSetIterator::NextFrame(bool validate) {
464 StackFrame* frame; 445 StackFrame* frame;
465 ASSERT(HasNext()); 446 ASSERT(HasNext());
466 frame = &stack_frame_; 447 frame = &stack_frame_;
467 frame->sp_ = sp_; 448 frame->sp_ = sp_;
468 frame->fp_ = fp_; 449 frame->fp_ = fp_;
469 frame->pc_ = pc_; 450 frame->pc_ = pc_;
470 sp_ = frame->GetCallerSp(); 451 sp_ = frame->GetCallerSp();
471 fp_ = frame->GetCallerFp(); 452 fp_ = frame->GetCallerFp();
472 pc_ = frame->GetCallerPc(); 453 pc_ = frame->GetCallerPc();
473 ASSERT((validate == kDontValidateFrames) || frame->IsValid()); 454 ASSERT((validate == kDontValidateFrames) || frame->IsValid());
474 return frame; 455 return frame;
475 } 456 }
476 457
477
478 ExitFrame* StackFrameIterator::NextExitFrame() { 458 ExitFrame* StackFrameIterator::NextExitFrame() {
479 exit_.sp_ = frames_.sp_; 459 exit_.sp_ = frames_.sp_;
480 exit_.fp_ = frames_.fp_; 460 exit_.fp_ = frames_.fp_;
481 exit_.pc_ = frames_.pc_; 461 exit_.pc_ = frames_.pc_;
482 frames_.sp_ = exit_.GetCallerSp(); 462 frames_.sp_ = exit_.GetCallerSp();
483 frames_.fp_ = exit_.GetCallerFp(); 463 frames_.fp_ = exit_.GetCallerFp();
484 frames_.pc_ = exit_.GetCallerPc(); 464 frames_.pc_ = exit_.GetCallerPc();
485 ASSERT(exit_.IsValid()); 465 ASSERT(exit_.IsValid());
486 return &exit_; 466 return &exit_;
487 } 467 }
488 468
489
490 EntryFrame* StackFrameIterator::NextEntryFrame() { 469 EntryFrame* StackFrameIterator::NextEntryFrame() {
491 ASSERT(!frames_.HasNext()); 470 ASSERT(!frames_.HasNext());
492 entry_.sp_ = frames_.sp_; 471 entry_.sp_ = frames_.sp_;
493 entry_.fp_ = frames_.fp_; 472 entry_.fp_ = frames_.fp_;
494 entry_.pc_ = frames_.pc_; 473 entry_.pc_ = frames_.pc_;
495 SetupNextExitFrameData(); // Setup data for next exit frame in chain. 474 SetupNextExitFrameData(); // Setup data for next exit frame in chain.
496 ASSERT(entry_.IsValid()); 475 ASSERT(entry_.IsValid());
497 return &entry_; 476 return &entry_;
498 } 477 }
499 478
500
501 InlinedFunctionsIterator::InlinedFunctionsIterator(const Code& code, uword pc) 479 InlinedFunctionsIterator::InlinedFunctionsIterator(const Code& code, uword pc)
502 : index_(0), 480 : index_(0),
503 num_materializations_(0), 481 num_materializations_(0),
504 dest_frame_size_(0), 482 dest_frame_size_(0),
505 code_(Code::Handle(code.raw())), 483 code_(Code::Handle(code.raw())),
506 deopt_info_(TypedData::Handle()), 484 deopt_info_(TypedData::Handle()),
507 function_(Function::Handle()), 485 function_(Function::Handle()),
508 pc_(pc), 486 pc_(pc),
509 deopt_instructions_(), 487 deopt_instructions_(),
510 object_table_(ObjectPool::Handle()) { 488 object_table_(ObjectPool::Handle()) {
(...skipping 18 matching lines...) Expand all
529 ASSERT(!deopt_table.IsNull()); 507 ASSERT(!deopt_table.IsNull());
530 DeoptInfo::Unpack(deopt_table, deopt_info_, &deopt_instructions_); 508 DeoptInfo::Unpack(deopt_table, deopt_info_, &deopt_instructions_);
531 num_materializations_ = DeoptInfo::NumMaterializations(deopt_instructions_); 509 num_materializations_ = DeoptInfo::NumMaterializations(deopt_instructions_);
532 dest_frame_size_ = DeoptInfo::FrameSize(deopt_info_); 510 dest_frame_size_ = DeoptInfo::FrameSize(deopt_info_);
533 object_table_ = code_.GetObjectPool(); 511 object_table_ = code_.GetObjectPool();
534 Advance(); 512 Advance();
535 } 513 }
536 #endif // defined(DART_PRECOMPILED_RUNTIME) 514 #endif // defined(DART_PRECOMPILED_RUNTIME)
537 } 515 }
538 516
539
540 void InlinedFunctionsIterator::Advance() { 517 void InlinedFunctionsIterator::Advance() {
541 // Iterate over the deopt instructions and determine the inlined 518 // Iterate over the deopt instructions and determine the inlined
542 // functions if any and iterate over them. 519 // functions if any and iterate over them.
543 ASSERT(!Done()); 520 ASSERT(!Done());
544 521
545 #if defined(DART_PRECOMPILED_RUNTIME) 522 #if defined(DART_PRECOMPILED_RUNTIME)
546 ASSERT(deopt_info_.IsNull()); 523 ASSERT(deopt_info_.IsNull());
547 SetDone(); 524 SetDone();
548 return; 525 return;
549 #else 526 #else
550 if (deopt_info_.IsNull()) { 527 if (deopt_info_.IsNull()) {
551 SetDone(); 528 SetDone();
552 return; 529 return;
553 } 530 }
554 531
555 ASSERT(deopt_instructions_.length() != 0); 532 ASSERT(deopt_instructions_.length() != 0);
556 while (index_ < deopt_instructions_.length()) { 533 while (index_ < deopt_instructions_.length()) {
557 DeoptInstr* deopt_instr = deopt_instructions_[index_++]; 534 DeoptInstr* deopt_instr = deopt_instructions_[index_++];
558 if (deopt_instr->kind() == DeoptInstr::kRetAddress) { 535 if (deopt_instr->kind() == DeoptInstr::kRetAddress) {
559 pc_ = DeoptInstr::GetRetAddress(deopt_instr, object_table_, &code_); 536 pc_ = DeoptInstr::GetRetAddress(deopt_instr, object_table_, &code_);
560 function_ = code_.function(); 537 function_ = code_.function();
561 return; 538 return;
562 } 539 }
563 } 540 }
564 SetDone(); 541 SetDone();
565 #endif // defined(DART_PRECOMPILED_RUNTIME) 542 #endif // defined(DART_PRECOMPILED_RUNTIME)
566 } 543 }
567 544
568
569 // Finds the potential offset for the current function's FP if the 545 // Finds the potential offset for the current function's FP if the
570 // current frame were to be deoptimized. 546 // current frame were to be deoptimized.
571 intptr_t InlinedFunctionsIterator::GetDeoptFpOffset() const { 547 intptr_t InlinedFunctionsIterator::GetDeoptFpOffset() const {
572 ASSERT(deopt_instructions_.length() != 0); 548 ASSERT(deopt_instructions_.length() != 0);
573 for (intptr_t index = index_; index < deopt_instructions_.length(); index++) { 549 for (intptr_t index = index_; index < deopt_instructions_.length(); index++) {
574 DeoptInstr* deopt_instr = deopt_instructions_[index]; 550 DeoptInstr* deopt_instr = deopt_instructions_[index];
575 if (deopt_instr->kind() == DeoptInstr::kCallerFp) { 551 if (deopt_instr->kind() == DeoptInstr::kCallerFp) {
576 intptr_t fp_offset = (index - num_materializations_); 552 intptr_t fp_offset = (index - num_materializations_);
577 #if defined(TARGET_ARCH_DBC) 553 #if defined(TARGET_ARCH_DBC)
578 // Stack on DBC is growing upwards but we record deopt commands 554 // Stack on DBC is growing upwards but we record deopt commands
579 // in the same order we record them on other architectures as if 555 // in the same order we record them on other architectures as if
580 // the stack was growing downwards. 556 // the stack was growing downwards.
581 fp_offset = dest_frame_size_ - fp_offset; 557 fp_offset = dest_frame_size_ - fp_offset;
582 #endif 558 #endif
583 return fp_offset; 559 return fp_offset;
584 } 560 }
585 } 561 }
586 UNREACHABLE(); 562 UNREACHABLE();
587 return 0; 563 return 0;
588 } 564 }
589 565
590
591 #if defined(DEBUG) 566 #if defined(DEBUG)
592 void ValidateFrames() { 567 void ValidateFrames() {
593 StackFrameIterator frames(StackFrameIterator::kValidateFrames, 568 StackFrameIterator frames(StackFrameIterator::kValidateFrames,
594 Thread::Current(), 569 Thread::Current(),
595 StackFrameIterator::kNoCrossThreadIteration); 570 StackFrameIterator::kNoCrossThreadIteration);
596 StackFrame* frame = frames.NextFrame(); 571 StackFrame* frame = frames.NextFrame();
597 while (frame != NULL) { 572 while (frame != NULL) {
598 frame = frames.NextFrame(); 573 frame = frames.NextFrame();
599 } 574 }
600 } 575 }
601 #endif 576 #endif
602 577
603
604 } // namespace dart 578 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/stack_frame.h ('k') | runtime/vm/stack_frame_dbc.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698