OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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/thread.h" | 5 #include "vm/thread.h" |
6 | 6 |
7 #include "vm/compiler_stats.h" | 7 #include "vm/compiler_stats.h" |
8 #include "vm/dart_api_state.h" | 8 #include "vm/dart_api_state.h" |
9 #include "vm/growable_array.h" | 9 #include "vm/growable_array.h" |
10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 StoreBufferRelease(StoreBuffer::kIgnoreThreshold); | 311 StoreBufferRelease(StoreBuffer::kIgnoreThreshold); |
312 // Make sure to get an *empty* block; the isolate needs all entries | 312 // Make sure to get an *empty* block; the isolate needs all entries |
313 // at GC time. | 313 // at GC time. |
314 // TODO(koda): Replace with an epilogue (PrepareAfterGC) that acquires. | 314 // TODO(koda): Replace with an epilogue (PrepareAfterGC) that acquires. |
315 store_buffer_block_ = isolate()->store_buffer()->PopEmptyBlock(); | 315 store_buffer_block_ = isolate()->store_buffer()->PopEmptyBlock(); |
316 } | 316 } |
317 | 317 |
318 | 318 |
319 void Thread::SetStackLimitFromStackBase(uword stack_base) { | 319 void Thread::SetStackLimitFromStackBase(uword stack_base) { |
320 // Set stack limit. | 320 // Set stack limit. |
| 321 #if !defined(TARGET_ARCH_DBC) |
321 #if defined(USING_SIMULATOR) | 322 #if defined(USING_SIMULATOR) |
322 // Ignore passed-in native stack top and use Simulator stack top. | 323 // Ignore passed-in native stack top and use Simulator stack top. |
323 Simulator* sim = Simulator::Current(); // May allocate a simulator. | 324 Simulator* sim = Simulator::Current(); // May allocate a simulator. |
324 ASSERT(isolate()->simulator() == sim); // Isolate's simulator is current one. | 325 ASSERT(isolate()->simulator() == sim); // Isolate's simulator is current one. |
325 stack_base = sim->StackTop(); | 326 stack_base = sim->StackTop(); |
326 // The overflow area is accounted for by the simulator. | 327 // The overflow area is accounted for by the simulator. |
327 #endif | 328 #endif |
328 SetStackLimit(stack_base - OSThread::GetSpecifiedStackSize()); | 329 SetStackLimit(stack_base - OSThread::GetSpecifiedStackSize()); |
| 330 #else |
| 331 SetStackLimit(Simulator::Current()->StackTop()); |
| 332 #endif // !defined(TARGET_ARCH_DBC) |
329 } | 333 } |
330 | 334 |
331 | 335 |
332 void Thread::SetStackLimit(uword limit) { | 336 void Thread::SetStackLimit(uword limit) { |
333 // The thread setting the stack limit is not necessarily the thread which | 337 // The thread setting the stack limit is not necessarily the thread which |
334 // the stack limit is being set on. | 338 // the stack limit is being set on. |
335 MonitorLocker ml(thread_lock_); | 339 MonitorLocker ml(thread_lock_); |
336 if (stack_limit_ == saved_stack_limit_) { | 340 if (stack_limit_ == saved_stack_limit_) { |
337 // No interrupt pending, set stack_limit_ too. | 341 // No interrupt pending, set stack_limit_ too. |
338 stack_limit_ = limit; | 342 stack_limit_ = limit; |
339 } | 343 } |
340 saved_stack_limit_ = limit; | 344 saved_stack_limit_ = limit; |
341 } | 345 } |
342 | 346 |
343 | 347 |
344 void Thread::ClearStackLimit() { | 348 void Thread::ClearStackLimit() { |
345 SetStackLimit(~static_cast<uword>(0)); | 349 SetStackLimit(~static_cast<uword>(0)); |
346 } | 350 } |
347 | 351 |
348 | 352 |
349 /* static */ | 353 /* static */ |
350 uword Thread::GetCurrentStackPointer() { | 354 uword Thread::GetCurrentStackPointer() { |
| 355 #if !defined(TARGET_ARCH_DBC) |
351 // Since AddressSanitizer's detect_stack_use_after_return instruments the | 356 // Since AddressSanitizer's detect_stack_use_after_return instruments the |
352 // C++ code to give out fake stack addresses, we call a stub in that case. | 357 // C++ code to give out fake stack addresses, we call a stub in that case. |
353 ASSERT(StubCode::GetStackPointer_entry() != NULL); | 358 ASSERT(StubCode::GetStackPointer_entry() != NULL); |
354 uword (*func)() = reinterpret_cast<uword (*)()>( | 359 uword (*func)() = reinterpret_cast<uword (*)()>( |
355 StubCode::GetStackPointer_entry()->EntryPoint()); | 360 StubCode::GetStackPointer_entry()->EntryPoint()); |
| 361 #else |
| 362 uword (*func)() = NULL; |
| 363 #endif |
356 // But for performance (and to support simulators), we normally use a local. | 364 // But for performance (and to support simulators), we normally use a local. |
357 #if defined(__has_feature) | 365 #if defined(__has_feature) |
358 #if __has_feature(address_sanitizer) | 366 #if __has_feature(address_sanitizer) |
359 uword current_sp = func(); | 367 uword current_sp = func(); |
360 return current_sp; | 368 return current_sp; |
361 #else | 369 #else |
362 uword stack_allocated_local_address = reinterpret_cast<uword>(&func); | 370 uword stack_allocated_local_address = reinterpret_cast<uword>(&func); |
363 return stack_allocated_local_address; | 371 return stack_allocated_local_address; |
364 #endif | 372 #endif |
365 #else | 373 #else |
(...skipping 17 matching lines...) Expand all Loading... |
383 uword defer_bits = interrupt_bits & deferred_interrupts_mask_; | 391 uword defer_bits = interrupt_bits & deferred_interrupts_mask_; |
384 if (defer_bits != 0) { | 392 if (defer_bits != 0) { |
385 deferred_interrupts_ |= defer_bits; | 393 deferred_interrupts_ |= defer_bits; |
386 interrupt_bits &= ~deferred_interrupts_mask_; | 394 interrupt_bits &= ~deferred_interrupts_mask_; |
387 if (interrupt_bits == 0) { | 395 if (interrupt_bits == 0) { |
388 return; | 396 return; |
389 } | 397 } |
390 } | 398 } |
391 | 399 |
392 if (stack_limit_ == saved_stack_limit_) { | 400 if (stack_limit_ == saved_stack_limit_) { |
393 stack_limit_ = (~static_cast<uword>(0)) & ~kInterruptsMask; | 401 stack_limit_ = kInterruptStackLimit & ~kInterruptsMask; |
394 } | 402 } |
395 stack_limit_ |= interrupt_bits; | 403 stack_limit_ |= interrupt_bits; |
396 } | 404 } |
397 | 405 |
398 | 406 |
399 uword Thread::GetAndClearInterrupts() { | 407 uword Thread::GetAndClearInterrupts() { |
400 MonitorLocker ml(thread_lock_); | 408 MonitorLocker ml(thread_lock_); |
401 if (stack_limit_ == saved_stack_limit_) { | 409 if (stack_limit_ == saved_stack_limit_) { |
402 return 0; // No interrupt was requested. | 410 return 0; // No interrupt was requested. |
403 } | 411 } |
(...skipping 26 matching lines...) Expand all Loading... |
430 } | 438 } |
431 } | 439 } |
432 | 440 |
433 | 441 |
434 void Thread::RestoreOOBMessageInterrupts() { | 442 void Thread::RestoreOOBMessageInterrupts() { |
435 MonitorLocker ml(thread_lock_); | 443 MonitorLocker ml(thread_lock_); |
436 ASSERT(deferred_interrupts_mask_ == kMessageInterrupt); | 444 ASSERT(deferred_interrupts_mask_ == kMessageInterrupt); |
437 deferred_interrupts_mask_ = 0; | 445 deferred_interrupts_mask_ = 0; |
438 if (deferred_interrupts_ != 0) { | 446 if (deferred_interrupts_ != 0) { |
439 if (stack_limit_ == saved_stack_limit_) { | 447 if (stack_limit_ == saved_stack_limit_) { |
440 stack_limit_ = (~static_cast<uword>(0)) & ~kInterruptsMask; | 448 stack_limit_ = kInterruptStackLimit & ~kInterruptsMask; |
441 } | 449 } |
442 stack_limit_ |= deferred_interrupts_; | 450 stack_limit_ |= deferred_interrupts_; |
443 deferred_interrupts_ = 0; | 451 deferred_interrupts_ = 0; |
444 } | 452 } |
445 if (FLAG_trace_service && FLAG_trace_service_verbose) { | 453 if (FLAG_trace_service && FLAG_trace_service_verbose) { |
446 OS::Print("[+%" Pd64 "ms] Isolate %s restoring OOB interrupts\n", | 454 OS::Print("[+%" Pd64 "ms] Isolate %s restoring OOB interrupts\n", |
447 Dart::timestamp(), isolate()->name()); | 455 Dart::timestamp(), isolate()->name()); |
448 } | 456 } |
449 } | 457 } |
450 | 458 |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
723 | 731 |
724 DisableThreadInterruptsScope::~DisableThreadInterruptsScope() { | 732 DisableThreadInterruptsScope::~DisableThreadInterruptsScope() { |
725 if (thread() != NULL) { | 733 if (thread() != NULL) { |
726 OSThread* os_thread = thread()->os_thread(); | 734 OSThread* os_thread = thread()->os_thread(); |
727 ASSERT(os_thread != NULL); | 735 ASSERT(os_thread != NULL); |
728 os_thread->EnableThreadInterrupts(); | 736 os_thread->EnableThreadInterrupts(); |
729 } | 737 } |
730 } | 738 } |
731 | 739 |
732 } // namespace dart | 740 } // namespace dart |
OLD | NEW |