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

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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 262
265 bool StackFrame::IsValid() const { 263 bool StackFrame::IsValid() const {
266 if (IsEntryFrame() || IsExitFrame() || IsStubFrame()) { 264 if (IsEntryFrame() || IsExitFrame() || IsStubFrame()) {
267 return true; 265 return true;
268 } 266 }
269 return (LookupDartCode() != Code::null()); 267 return (LookupDartCode() != Code::null());
270 } 268 }
271 269
272 270
273 void StackFrameIterator::SetupLastExitFrameData() { 271 void StackFrameIterator::SetupLastExitFrameData() {
274 uword exit_marker = Thread::Current()->top_exit_frame_info(); 272 ASSERT(thread_ != NULL);
273 uword exit_marker = thread_->top_exit_frame_info();
srdjan 2015/10/20 21:33:47 Please sync with my temporary fix and remove Isola
Cutch 2015/10/20 21:39:01 Done.
275 frames_.fp_ = exit_marker; 274 frames_.fp_ = exit_marker;
276 } 275 }
277 276
278 277
279 void StackFrameIterator::SetupNextExitFrameData() { 278 void StackFrameIterator::SetupNextExitFrameData() {
280 uword exit_address = entry_.fp() + (kExitLinkSlotFromEntryFp * kWordSize); 279 uword exit_address = entry_.fp() + (kExitLinkSlotFromEntryFp * kWordSize);
281 uword exit_marker = *reinterpret_cast<uword*>(exit_address); 280 uword exit_marker = *reinterpret_cast<uword*>(exit_address);
282 frames_.fp_ = exit_marker; 281 frames_.fp_ = exit_marker;
283 frames_.sp_ = 0; 282 frames_.sp_ = 0;
284 frames_.pc_ = 0; 283 frames_.pc_ = 0;
285 } 284 }
286 285
287 286
288 // Tell MemorySanitizer that generated code initializes part of the stack. 287 // Tell MemorySanitizer that generated code initializes part of the stack.
289 // 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.
290 static void UnpoisonStack(Isolate* isolate, uword fp) { 289 static void UnpoisonStack(Isolate* isolate, uword fp) {
291 ASSERT(fp != 0); 290 ASSERT(fp != 0);
292 uword size = isolate->GetSpecifiedStackSize(); 291 uword size = isolate->GetSpecifiedStackSize();
293 MSAN_UNPOISON(reinterpret_cast<void*>(fp - size), 2 * size); 292 MSAN_UNPOISON(reinterpret_cast<void*>(fp - size), 2 * size);
294 } 293 }
295 294
296 295
297 StackFrameIterator::StackFrameIterator(bool validate, Isolate* isolate) 296 StackFrameIterator::StackFrameIterator(bool validate,
297 Thread* thread)
srdjan 2015/10/20 21:33:47 One line.
Cutch 2015/10/20 21:39:01 Done.
298 : validate_(validate), 298 : validate_(validate),
299 entry_(isolate), 299 entry_(thread),
300 exit_(isolate), 300 exit_(thread),
301 frames_(isolate), 301 frames_(thread),
302 current_frame_(NULL), 302 current_frame_(NULL),
303 isolate_(isolate) { 303 thread_(thread) {
304 ASSERT((isolate_ == Isolate::Current()) || 304 ASSERT((thread_ == Thread::Current()) ||
305 OS::AllowStackFrameIteratorFromAnotherThread()); 305 OS::AllowStackFrameIteratorFromAnotherThread());
306 SetupLastExitFrameData(); // Setup data for last exit frame. 306 SetupLastExitFrameData(); // Setup data for last exit frame.
307 } 307 }
308 308
309 309
310 StackFrameIterator::StackFrameIterator(uword last_fp, bool validate, 310 StackFrameIterator::StackFrameIterator(uword last_fp, bool validate,
311 Isolate* isolate) 311 Thread* thread)
312 : validate_(validate), 312 : validate_(validate),
313 entry_(isolate), 313 entry_(thread),
314 exit_(isolate), 314 exit_(thread),
315 frames_(isolate), 315 frames_(thread),
316 current_frame_(NULL), 316 current_frame_(NULL),
317 isolate_(isolate) { 317 thread_(thread) {
318 ASSERT((isolate_ == Isolate::Current()) || 318 ASSERT((thread_ == Thread::Current()) ||
319 OS::AllowStackFrameIteratorFromAnotherThread()); 319 OS::AllowStackFrameIteratorFromAnotherThread());
320 frames_.fp_ = last_fp; 320 frames_.fp_ = last_fp;
321 frames_.sp_ = 0; 321 frames_.sp_ = 0;
322 frames_.pc_ = 0; 322 frames_.pc_ = 0;
323 } 323 }
324 324
325 325
326 StackFrameIterator::StackFrameIterator(uword fp, uword sp, uword pc, 326 StackFrameIterator::StackFrameIterator(uword fp, uword sp, uword pc,
327 bool validate, Isolate* isolate) 327 bool validate, Thread* thread)
328 : validate_(validate), 328 : validate_(validate),
329 entry_(isolate), 329 entry_(thread),
330 exit_(isolate), 330 exit_(thread),
331 frames_(isolate), 331 frames_(thread),
332 current_frame_(NULL), 332 current_frame_(NULL),
333 isolate_(isolate) { 333 thread_(thread) {
334 ASSERT((isolate_ == Isolate::Current()) || 334 ASSERT((thread_ == Thread::Current()) ||
335 OS::AllowStackFrameIteratorFromAnotherThread()); 335 OS::AllowStackFrameIteratorFromAnotherThread());
336 frames_.fp_ = fp; 336 frames_.fp_ = fp;
337 frames_.sp_ = sp; 337 frames_.sp_ = sp;
338 frames_.pc_ = pc; 338 frames_.pc_ = pc;
339 } 339 }
340 340
341 341
342 StackFrame* StackFrameIterator::NextFrame() { 342 StackFrame* StackFrameIterator::NextFrame() {
343 // When we are at the start of iteration after having created an 343 // When we are at the start of iteration after having created an
344 // iterator object, current_frame_ will be NULL as we haven't seen 344 // iterator object, current_frame_ will be NULL as we haven't seen
345 // any frames yet (unless we start iterating in the simulator from a given 345 // any frames yet (unless we start iterating in the simulator from a given
346 // triplet of fp, sp, and pc). At this point, if NextFrame is called, it tries 346 // triplet of fp, sp, and pc). At this point, if NextFrame is called, it tries
347 // to set up the next exit frame by reading the top_exit_frame_info 347 // to set up the next exit frame by reading the top_exit_frame_info
348 // from the isolate. If we do not have any dart invocations yet, 348 // from the isolate. If we do not have any dart invocations yet,
349 // top_exit_frame_info will be 0 and so we would return NULL. 349 // top_exit_frame_info will be 0 and so we would return NULL.
350 350
351 // current_frame_ will also be NULL, when we are at the end of having 351 // current_frame_ will also be NULL, when we are at the end of having
352 // iterated through all the frames. If NextFrame is called at this 352 // iterated through all the frames. If NextFrame is called at this
353 // point, we will try and set up the next exit frame, but since we are 353 // point, we will try and set up the next exit frame, but since we are
354 // at the end of the iteration, fp_ will be 0 and we would return NULL. 354 // at the end of the iteration, fp_ will be 0 and we would return NULL.
355 if (current_frame_ == NULL) { 355 if (current_frame_ == NULL) {
356 if (!HasNextFrame()) { 356 if (!HasNextFrame()) {
357 return NULL; 357 return NULL;
358 } 358 }
359 UnpoisonStack(isolate_, frames_.fp_); 359 UnpoisonStack(thread_->isolate(), frames_.fp_);
360 if (frames_.pc_ == 0) { 360 if (frames_.pc_ == 0) {
361 // Iteration starts from an exit frame given by its fp. 361 // Iteration starts from an exit frame given by its fp.
362 current_frame_ = NextExitFrame(); 362 current_frame_ = NextExitFrame();
363 } else if (*(reinterpret_cast<uword*>( 363 } else if (*(reinterpret_cast<uword*>(
364 frames_.fp_ + (kSavedCallerFpSlotFromFp * kWordSize))) == 0) { 364 frames_.fp_ + (kSavedCallerFpSlotFromFp * kWordSize))) == 0) {
365 // Iteration starts from an entry frame given by its fp, sp, and pc. 365 // Iteration starts from an entry frame given by its fp, sp, and pc.
366 current_frame_ = NextEntryFrame(); 366 current_frame_ = NextEntryFrame();
367 } else { 367 } else {
368 // Iteration starts from a Dart or stub frame given by its fp, sp, and pc. 368 // Iteration starts from a Dart or stub frame given by its fp, sp, and pc.
369 current_frame_ = frames_.NextFrame(validate_); 369 current_frame_ = frames_.NextFrame(validate_);
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 if (deopt_instr->kind() == DeoptInstr::kCallerFp) { 496 if (deopt_instr->kind() == DeoptInstr::kCallerFp) {
497 return (index - num_materializations_); 497 return (index - num_materializations_);
498 } 498 }
499 } 499 }
500 UNREACHABLE(); 500 UNREACHABLE();
501 return 0; 501 return 0;
502 } 502 }
503 503
504 504
505 } // namespace dart 505 } // 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