| 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 |