OLD | NEW |
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 "vm/assembler.h" | 8 #include "vm/assembler.h" |
8 #include "vm/deopt_instructions.h" | 9 #include "vm/deopt_instructions.h" |
9 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
10 #include "vm/object.h" | 11 #include "vm/object.h" |
11 #include "vm/object_store.h" | 12 #include "vm/object_store.h" |
12 #include "vm/os.h" | 13 #include "vm/os.h" |
13 #include "vm/parser.h" | 14 #include "vm/parser.h" |
14 #include "vm/raw_object.h" | 15 #include "vm/raw_object.h" |
15 #include "vm/reusable_handles.h" | 16 #include "vm/reusable_handles.h" |
16 #include "vm/stub_code.h" | 17 #include "vm/stub_code.h" |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 | 272 |
272 void StackFrameIterator::SetupNextExitFrameData() { | 273 void StackFrameIterator::SetupNextExitFrameData() { |
273 uword exit_address = entry_.fp() + (kExitLinkSlotFromEntryFp * kWordSize); | 274 uword exit_address = entry_.fp() + (kExitLinkSlotFromEntryFp * kWordSize); |
274 uword exit_marker = *reinterpret_cast<uword*>(exit_address); | 275 uword exit_marker = *reinterpret_cast<uword*>(exit_address); |
275 frames_.fp_ = exit_marker; | 276 frames_.fp_ = exit_marker; |
276 frames_.sp_ = 0; | 277 frames_.sp_ = 0; |
277 frames_.pc_ = 0; | 278 frames_.pc_ = 0; |
278 } | 279 } |
279 | 280 |
280 | 281 |
| 282 // Tell MemorySanitizer that generated code initializes part of the stack. |
| 283 // TODO(koda): Limit to frames that are actually written by generated code. |
| 284 static void UnpoisonStack(Isolate* isolate, uword fp) { |
| 285 ASSERT(fp != 0); |
| 286 uword size = isolate->GetSpecifiedStackSize(); |
| 287 MSAN_UNPOISON(reinterpret_cast<void*>(fp - size), 2 * size); |
| 288 } |
| 289 |
| 290 |
281 StackFrameIterator::StackFrameIterator(bool validate, Isolate* isolate) | 291 StackFrameIterator::StackFrameIterator(bool validate, Isolate* isolate) |
282 : validate_(validate), | 292 : validate_(validate), |
283 entry_(isolate), | 293 entry_(isolate), |
284 exit_(isolate), | 294 exit_(isolate), |
285 frames_(isolate), | 295 frames_(isolate), |
286 current_frame_(NULL), | 296 current_frame_(NULL), |
287 isolate_(isolate) { | 297 isolate_(isolate) { |
288 ASSERT((isolate_ == Isolate::Current()) || | 298 ASSERT((isolate_ == Isolate::Current()) || |
289 OS::AllowStackFrameIteratorFromAnotherThread()); | 299 OS::AllowStackFrameIteratorFromAnotherThread()); |
290 SetupLastExitFrameData(); // Setup data for last exit frame. | 300 SetupLastExitFrameData(); // Setup data for last exit frame. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 // top_exit_frame_info will be 0 and so we would return NULL. | 343 // top_exit_frame_info will be 0 and so we would return NULL. |
334 | 344 |
335 // current_frame_ will also be NULL, when we are at the end of having | 345 // current_frame_ will also be NULL, when we are at the end of having |
336 // iterated through all the frames. If NextFrame is called at this | 346 // iterated through all the frames. If NextFrame is called at this |
337 // point, we will try and set up the next exit frame, but since we are | 347 // point, we will try and set up the next exit frame, but since we are |
338 // at the end of the iteration, fp_ will be 0 and we would return NULL. | 348 // at the end of the iteration, fp_ will be 0 and we would return NULL. |
339 if (current_frame_ == NULL) { | 349 if (current_frame_ == NULL) { |
340 if (!HasNextFrame()) { | 350 if (!HasNextFrame()) { |
341 return NULL; | 351 return NULL; |
342 } | 352 } |
| 353 UnpoisonStack(isolate_, frames_.fp_); |
343 if (frames_.pc_ == 0) { | 354 if (frames_.pc_ == 0) { |
344 // Iteration starts from an exit frame given by its fp. | 355 // Iteration starts from an exit frame given by its fp. |
345 current_frame_ = NextExitFrame(); | 356 current_frame_ = NextExitFrame(); |
346 } else if (*(reinterpret_cast<uword*>( | 357 } else if (*(reinterpret_cast<uword*>( |
347 frames_.fp_ + (kSavedCallerFpSlotFromFp * kWordSize))) == 0) { | 358 frames_.fp_ + (kSavedCallerFpSlotFromFp * kWordSize))) == 0) { |
348 // Iteration starts from an entry frame given by its fp, sp, and pc. | 359 // Iteration starts from an entry frame given by its fp, sp, and pc. |
349 current_frame_ = NextEntryFrame(); | 360 current_frame_ = NextEntryFrame(); |
350 } else { | 361 } else { |
351 // Iteration starts from a Dart or stub frame given by its fp, sp, and pc. | 362 // Iteration starts from a Dart or stub frame given by its fp, sp, and pc. |
352 current_frame_ = frames_.NextFrame(validate_); | 363 current_frame_ = frames_.NextFrame(validate_); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 if (deopt_instr->kind() == DeoptInstr::kCallerFp) { | 490 if (deopt_instr->kind() == DeoptInstr::kCallerFp) { |
480 return (index - num_materializations_); | 491 return (index - num_materializations_); |
481 } | 492 } |
482 } | 493 } |
483 UNREACHABLE(); | 494 UNREACHABLE(); |
484 return 0; | 495 return 0; |
485 } | 496 } |
486 | 497 |
487 | 498 |
488 } // namespace dart | 499 } // namespace dart |
OLD | NEW |