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

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

Issue 1411703004: Pass Thread into StackFrameIterator (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 2 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') | 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 "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"
(...skipping 17 matching lines...) Expand all
28 NoSafepointScope no_safepoint; 28 NoSafepointScope no_safepoint;
29 #endif 29 #endif
30 RawCode* code = GetCodeObject(); 30 RawCode* code = GetCodeObject();
31 intptr_t cid = code->ptr()->owner_->GetClassId(); 31 intptr_t cid = code->ptr()->owner_->GetClassId();
32 ASSERT(cid == kNullCid || cid == kClassCid || cid == kFunctionCid); 32 ASSERT(cid == kNullCid || cid == kClassCid || cid == kFunctionCid);
33 return cid == kNullCid || cid == kClassCid; 33 return cid == kNullCid || cid == kClassCid;
34 } 34 }
35 35
36 36
37 const char* StackFrame::ToCString() const { 37 const char* StackFrame::ToCString() const {
38 ASSERT(isolate_ == Isolate::Current()); 38 ASSERT(thread_ == Thread::Current());
39 Zone* zone = Thread::Current()->zone(); 39 Zone* zone = Thread::Current()->zone();
40 if (IsDartFrame()) { 40 if (IsDartFrame()) {
41 const Code& code = Code::Handle(LookupDartCode()); 41 const Code& code = Code::Handle(LookupDartCode());
42 ASSERT(!code.IsNull()); 42 ASSERT(!code.IsNull());
43 const Object& owner = Object::Handle(code.owner()); 43 const Object& owner = Object::Handle(code.owner());
44 ASSERT(!owner.IsNull()); 44 ASSERT(!owner.IsNull());
45 if (owner.IsFunction()) { 45 if (owner.IsFunction()) {
46 const Function& function = Function::Cast(owner); 46 const Function& function = Function::Cast(owner);
47 return zone->PrintToString( 47 return zone->PrintToString(
48 "[%-8s : sp(%#" Px ") fp(%#" Px ") pc(%#" Px ") %s ]", 48 "[%-8s : sp(%#" Px ") fp(%#" Px ") pc(%#" Px ") %s ]",
(...skipping 12 matching lines...) Expand all
61 } 61 }
62 } 62 }
63 63
64 64
65 void ExitFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { 65 void ExitFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) {
66 // There are no objects to visit in this frame. 66 // There are no objects to visit in this frame.
67 } 67 }
68 68
69 69
70 void EntryFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { 70 void EntryFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) {
71 ASSERT(isolate() == Isolate::Current()); 71 ASSERT(thread() == Thread::Current());
72 // Visit objects between SP and (FP - callee_save_area). 72 // Visit objects between SP and (FP - callee_save_area).
73 ASSERT(visitor != NULL); 73 ASSERT(visitor != NULL);
74 RawObject** first = reinterpret_cast<RawObject**>(sp()); 74 RawObject** first = reinterpret_cast<RawObject**>(sp());
75 RawObject** last = reinterpret_cast<RawObject**>( 75 RawObject** last = reinterpret_cast<RawObject**>(
76 fp() + (kExitLinkSlotFromEntryFp - 1) * kWordSize); 76 fp() + (kExitLinkSlotFromEntryFp - 1) * kWordSize);
77 visitor->VisitPointers(first, last); 77 visitor->VisitPointers(first, last);
78 } 78 }
79 79
80 80
81 void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { 81 void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) {
82 // NOTE: This code runs while GC is in progress and runs within 82 // NOTE: This code runs while GC is in progress and runs within
83 // a NoHandleScope block. Hence it is not ok to use regular Zone or 83 // a NoHandleScope block. Hence it is not ok to use regular Zone or
84 // Scope handles. We use direct stack handles, the raw pointers in 84 // Scope handles. We use direct stack handles, the raw pointers in
85 // these handles are not traversed. The use of handles is mainly to 85 // these handles are not traversed. The use of handles is mainly to
86 // be able to reuse the handle based code and avoid having to add 86 // be able to reuse the handle based code and avoid having to add
87 // helper functions to the raw object interface. 87 // helper functions to the raw object interface.
88 ASSERT(isolate_ == Isolate::Current()); 88 ASSERT(thread() == Thread::Current());
89 ASSERT(visitor != NULL); 89 ASSERT(visitor != NULL);
90 NoSafepointScope no_safepoint; 90 NoSafepointScope no_safepoint;
91 Code code; 91 Code code;
92 code = LookupDartCode(); 92 code = LookupDartCode();
93 if (!code.IsNull()) { 93 if (!code.IsNull()) {
94 // Visit the code object. 94 // Visit the code object.
95 RawObject* raw_code = code.raw(); 95 RawObject* raw_code = code.raw();
96 visitor->VisitPointer(&raw_code); 96 visitor->VisitPointer(&raw_code);
97 97
98 // Optimized frames have a stack map. We need to visit the frame based 98 // Optimized frames have a stack map. We need to visit the frame based
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 // For normal unoptimized Dart frames and Stub frames each slot 158 // For normal unoptimized Dart frames and Stub frames each slot
159 // between the first and last included are tagged objects. 159 // between the first and last included are tagged objects.
160 RawObject** first = reinterpret_cast<RawObject**>(sp()); 160 RawObject** first = reinterpret_cast<RawObject**>(sp());
161 RawObject** last = reinterpret_cast<RawObject**>( 161 RawObject** last = reinterpret_cast<RawObject**>(
162 fp() + (kFirstObjectSlotFromFp * kWordSize)); 162 fp() + (kFirstObjectSlotFromFp * kWordSize));
163 visitor->VisitPointers(first, last); 163 visitor->VisitPointers(first, last);
164 } 164 }
165 165
166 166
167 RawFunction* StackFrame::LookupDartFunction() const { 167 RawFunction* StackFrame::LookupDartFunction() const {
168 ASSERT(isolate_ == Isolate::Current());
169 const Code& code = Code::Handle(LookupDartCode()); 168 const Code& code = Code::Handle(LookupDartCode());
170 if (!code.IsNull()) { 169 if (!code.IsNull()) {
171 return code.function(); 170 return code.function();
172 } 171 }
173 return Function::null(); 172 return Function::null();
174 } 173 }
175 174
176 175
177 RawCode* StackFrame::LookupDartCode() const { 176 RawCode* StackFrame::LookupDartCode() const {
178 ASSERT(isolate_ == Isolate::Current());
179 // We add a no gc scope to ensure that the code below does not trigger 177 // We add a no gc scope to ensure that the code below does not trigger
180 // a GC as we are handling raw object references here. It is possible 178 // a GC as we are handling raw object references here. It is possible
181 // that the code is called while a GC is in progress, that is ok. 179 // that the code is called while a GC is in progress, that is ok.
182 #if !defined(TARGET_OS_WINDOWS) 180 #if !defined(TARGET_OS_WINDOWS)
183 // On Windows, the profiler calls this from a separate thread where 181 // On Windows, the profiler calls this from a separate thread where
184 // Thread::Current() is NULL, so we cannot create a NoSafepointScope. 182 // Thread::Current() is NULL, so we cannot create a NoSafepointScope.
185 NoSafepointScope no_safepoint; 183 NoSafepointScope no_safepoint;
186 #endif 184 #endif
187 RawCode* code = GetCodeObject(); 185 RawCode* code = GetCodeObject();
188 if ((code != Code::null()) && 186 if ((code != Code::null()) &&
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 261
264 bool StackFrame::IsValid() const { 262 bool StackFrame::IsValid() const {
265 if (IsEntryFrame() || IsExitFrame() || IsStubFrame()) { 263 if (IsEntryFrame() || IsExitFrame() || IsStubFrame()) {
266 return true; 264 return true;
267 } 265 }
268 return (LookupDartCode() != Code::null()); 266 return (LookupDartCode() != Code::null());
269 } 267 }
270 268
271 269
272 void StackFrameIterator::SetupLastExitFrameData() { 270 void StackFrameIterator::SetupLastExitFrameData() {
273 // This gets called by profiler which may run in a different thread (Windows) 271 ASSERT(thread_ != NULL);
274 // but needs the info from mutator_thread instead. 272 uword exit_marker = thread_->top_exit_frame_info();
275 uword exit_marker = isolate_->top_exit_frame_info();
276 frames_.fp_ = exit_marker; 273 frames_.fp_ = exit_marker;
277 } 274 }
278 275
279 276
280 void StackFrameIterator::SetupNextExitFrameData() { 277 void StackFrameIterator::SetupNextExitFrameData() {
281 uword exit_address = entry_.fp() + (kExitLinkSlotFromEntryFp * kWordSize); 278 uword exit_address = entry_.fp() + (kExitLinkSlotFromEntryFp * kWordSize);
282 uword exit_marker = *reinterpret_cast<uword*>(exit_address); 279 uword exit_marker = *reinterpret_cast<uword*>(exit_address);
283 frames_.fp_ = exit_marker; 280 frames_.fp_ = exit_marker;
284 frames_.sp_ = 0; 281 frames_.sp_ = 0;
285 frames_.pc_ = 0; 282 frames_.pc_ = 0;
286 } 283 }
287 284
288 285
286 // TODO(johnmccutchan): Remove |isolate| argument.
289 // Tell MemorySanitizer that generated code initializes part of the stack. 287 // Tell MemorySanitizer that generated code initializes part of the stack.
290 // TODO(koda): Limit to frames that are actually written by generated code. 288 // TODO(koda): Limit to frames that are actually written by generated code.
291 static void UnpoisonStack(Isolate* isolate, uword fp) { 289 static void UnpoisonStack(Isolate* isolate, uword fp) {
292 ASSERT(fp != 0); 290 ASSERT(fp != 0);
293 uword size = isolate->GetSpecifiedStackSize(); 291 uword size = isolate->GetSpecifiedStackSize();
294 MSAN_UNPOISON(reinterpret_cast<void*>(fp - size), 2 * size); 292 MSAN_UNPOISON(reinterpret_cast<void*>(fp - size), 2 * size);
295 } 293 }
296 294
297 295
298 StackFrameIterator::StackFrameIterator(bool validate, Isolate* isolate) 296 StackFrameIterator::StackFrameIterator(bool validate, Thread* thread)
299 : validate_(validate), 297 : validate_(validate),
300 entry_(isolate), 298 entry_(thread),
301 exit_(isolate), 299 exit_(thread),
302 frames_(isolate), 300 frames_(thread),
303 current_frame_(NULL), 301 current_frame_(NULL),
304 isolate_(isolate) { 302 thread_(thread) {
305 ASSERT((isolate_ == Isolate::Current()) || 303 ASSERT((thread_ == Thread::Current()) ||
306 OS::AllowStackFrameIteratorFromAnotherThread()); 304 OS::AllowStackFrameIteratorFromAnotherThread());
307 SetupLastExitFrameData(); // Setup data for last exit frame. 305 SetupLastExitFrameData(); // Setup data for last exit frame.
308 } 306 }
309 307
310 308
311 StackFrameIterator::StackFrameIterator(uword last_fp, bool validate, 309 StackFrameIterator::StackFrameIterator(uword last_fp, bool validate,
312 Isolate* isolate) 310 Thread* thread)
313 : validate_(validate), 311 : validate_(validate),
314 entry_(isolate), 312 entry_(thread),
315 exit_(isolate), 313 exit_(thread),
316 frames_(isolate), 314 frames_(thread),
317 current_frame_(NULL), 315 current_frame_(NULL),
318 isolate_(isolate) { 316 thread_(thread) {
319 ASSERT((isolate_ == Isolate::Current()) || 317 ASSERT((thread_ == Thread::Current()) ||
320 OS::AllowStackFrameIteratorFromAnotherThread()); 318 OS::AllowStackFrameIteratorFromAnotherThread());
321 frames_.fp_ = last_fp; 319 frames_.fp_ = last_fp;
322 frames_.sp_ = 0; 320 frames_.sp_ = 0;
323 frames_.pc_ = 0; 321 frames_.pc_ = 0;
324 } 322 }
325 323
326 324
327 StackFrameIterator::StackFrameIterator(uword fp, uword sp, uword pc, 325 StackFrameIterator::StackFrameIterator(uword fp, uword sp, uword pc,
328 bool validate, Isolate* isolate) 326 bool validate, Thread* thread)
329 : validate_(validate), 327 : validate_(validate),
330 entry_(isolate), 328 entry_(thread),
331 exit_(isolate), 329 exit_(thread),
332 frames_(isolate), 330 frames_(thread),
333 current_frame_(NULL), 331 current_frame_(NULL),
334 isolate_(isolate) { 332 thread_(thread) {
335 ASSERT((isolate_ == Isolate::Current()) || 333 ASSERT((thread_ == Thread::Current()) ||
336 OS::AllowStackFrameIteratorFromAnotherThread()); 334 OS::AllowStackFrameIteratorFromAnotherThread());
337 frames_.fp_ = fp; 335 frames_.fp_ = fp;
338 frames_.sp_ = sp; 336 frames_.sp_ = sp;
339 frames_.pc_ = pc; 337 frames_.pc_ = pc;
340 } 338 }
341 339
342 340
343 StackFrame* StackFrameIterator::NextFrame() { 341 StackFrame* StackFrameIterator::NextFrame() {
344 // When we are at the start of iteration after having created an 342 // When we are at the start of iteration after having created an
345 // iterator object, current_frame_ will be NULL as we haven't seen 343 // iterator object, current_frame_ will be NULL as we haven't seen
346 // any frames yet (unless we start iterating in the simulator from a given 344 // any frames yet (unless we start iterating in the simulator from a given
347 // triplet of fp, sp, and pc). At this point, if NextFrame is called, it tries 345 // triplet of fp, sp, and pc). At this point, if NextFrame is called, it tries
348 // to set up the next exit frame by reading the top_exit_frame_info 346 // to set up the next exit frame by reading the top_exit_frame_info
349 // from the isolate. If we do not have any dart invocations yet, 347 // from the isolate. If we do not have any dart invocations yet,
350 // top_exit_frame_info will be 0 and so we would return NULL. 348 // top_exit_frame_info will be 0 and so we would return NULL.
351 349
352 // current_frame_ will also be NULL, when we are at the end of having 350 // current_frame_ will also be NULL, when we are at the end of having
353 // iterated through all the frames. If NextFrame is called at this 351 // iterated through all the frames. If NextFrame is called at this
354 // point, we will try and set up the next exit frame, but since we are 352 // point, we will try and set up the next exit frame, but since we are
355 // at the end of the iteration, fp_ will be 0 and we would return NULL. 353 // at the end of the iteration, fp_ will be 0 and we would return NULL.
356 if (current_frame_ == NULL) { 354 if (current_frame_ == NULL) {
357 if (!HasNextFrame()) { 355 if (!HasNextFrame()) {
358 return NULL; 356 return NULL;
359 } 357 }
360 UnpoisonStack(isolate_, frames_.fp_); 358 UnpoisonStack(thread_->isolate(), frames_.fp_);
361 if (frames_.pc_ == 0) { 359 if (frames_.pc_ == 0) {
362 // Iteration starts from an exit frame given by its fp. 360 // Iteration starts from an exit frame given by its fp.
363 current_frame_ = NextExitFrame(); 361 current_frame_ = NextExitFrame();
364 } else if (*(reinterpret_cast<uword*>( 362 } else if (*(reinterpret_cast<uword*>(
365 frames_.fp_ + (kSavedCallerFpSlotFromFp * kWordSize))) == 0) { 363 frames_.fp_ + (kSavedCallerFpSlotFromFp * kWordSize))) == 0) {
366 // Iteration starts from an entry frame given by its fp, sp, and pc. 364 // Iteration starts from an entry frame given by its fp, sp, and pc.
367 current_frame_ = NextEntryFrame(); 365 current_frame_ = NextEntryFrame();
368 } else { 366 } else {
369 // Iteration starts from a Dart or stub frame given by its fp, sp, and pc. 367 // Iteration starts from a Dart or stub frame given by its fp, sp, and pc.
370 current_frame_ = frames_.NextFrame(validate_); 368 current_frame_ = frames_.NextFrame(validate_);
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 if (deopt_instr->kind() == DeoptInstr::kCallerFp) { 495 if (deopt_instr->kind() == DeoptInstr::kCallerFp) {
498 return (index - num_materializations_); 496 return (index - num_materializations_);
499 } 497 }
500 } 498 }
501 UNREACHABLE(); 499 UNREACHABLE();
502 return 0; 500 return 0;
503 } 501 }
504 502
505 503
506 } // namespace dart 504 } // 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