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

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

Issue 1812753002: - Move (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 9 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
« runtime/vm/intermediate_language_arm.cc ('K') | « runtime/vm/thread.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) 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/dart_api_state.h" 7 #include "vm/dart_api_state.h"
8 #include "vm/growable_array.h" 8 #include "vm/growable_array.h"
9 #include "vm/isolate.h" 9 #include "vm/isolate.h"
10 #include "vm/lockers.h" 10 #include "vm/lockers.h"
11 #include "vm/log.h" 11 #include "vm/log.h"
12 #include "vm/message_handler.h"
12 #include "vm/native_entry.h" 13 #include "vm/native_entry.h"
13 #include "vm/object.h" 14 #include "vm/object.h"
14 #include "vm/os_thread.h" 15 #include "vm/os_thread.h"
15 #include "vm/profiler.h" 16 #include "vm/profiler.h"
16 #include "vm/runtime_entry.h" 17 #include "vm/runtime_entry.h"
17 #include "vm/stub_code.h" 18 #include "vm/stub_code.h"
18 #include "vm/symbols.h" 19 #include "vm/symbols.h"
19 #include "vm/thread_interrupter.h" 20 #include "vm/thread_interrupter.h"
20 #include "vm/thread_registry.h" 21 #include "vm/thread_registry.h"
21 22
22 namespace dart { 23 namespace dart {
23 24
25
26 DECLARE_FLAG(bool, trace_isolates);
27 DECLARE_FLAG(bool, trace_service);
28 DECLARE_FLAG(bool, trace_service_verbose);
29
30
24 Thread::~Thread() { 31 Thread::~Thread() {
25 // We should cleanly exit any isolate before destruction. 32 // We should cleanly exit any isolate before destruction.
26 ASSERT(isolate_ == NULL); 33 ASSERT(isolate_ == NULL);
27 // There should be no top api scopes at this point. 34 // There should be no top api scopes at this point.
28 ASSERT(api_top_scope() == NULL); 35 ASSERT(api_top_scope() == NULL);
29 // Delete the resusable api scope if there is one. 36 // Delete the resusable api scope if there is one.
30 if (api_reusable_scope_) { 37 if (api_reusable_scope_) {
31 delete api_reusable_scope_; 38 delete api_reusable_scope_;
32 api_reusable_scope_ = NULL; 39 api_reusable_scope_ = NULL;
33 } 40 }
34 delete thread_lock_; 41 delete thread_lock_;
35 thread_lock_ = NULL; 42 thread_lock_ = NULL;
36 } 43 }
37 44
38 45
39 #if defined(DEBUG) 46 #if defined(DEBUG)
40 #define REUSABLE_HANDLE_SCOPE_INIT(object) \ 47 #define REUSABLE_HANDLE_SCOPE_INIT(object) \
41 reusable_##object##_handle_scope_active_(false), 48 reusable_##object##_handle_scope_active_(false),
42 #else 49 #else
43 #define REUSABLE_HANDLE_SCOPE_INIT(object) 50 #define REUSABLE_HANDLE_SCOPE_INIT(object)
44 #endif // defined(DEBUG) 51 #endif // defined(DEBUG)
45 52
46 #define REUSABLE_HANDLE_INITIALIZERS(object) \ 53 #define REUSABLE_HANDLE_INITIALIZERS(object) \
47 object##_handle_(NULL), 54 object##_handle_(NULL),
48 55
49 56
50 Thread::Thread(Isolate* isolate) 57 Thread::Thread(Isolate* isolate)
51 : BaseThread(false), 58 : BaseThread(false),
59 stack_limit_(0),
60 stack_overflow_flags_(0),
61 isolate_(NULL),
62 heap_(NULL),
63 top_exit_frame_info_(0),
64 store_buffer_block_(NULL),
65 vm_tag_(0),
52 os_thread_(NULL), 66 os_thread_(NULL),
53 thread_lock_(new Monitor()), 67 thread_lock_(new Monitor()),
54 isolate_(NULL),
55 heap_(NULL),
56 zone_(NULL), 68 zone_(NULL),
57 api_reusable_scope_(NULL), 69 api_reusable_scope_(NULL),
58 api_top_scope_(NULL), 70 api_top_scope_(NULL),
59 top_exit_frame_info_(0),
60 top_resource_(NULL), 71 top_resource_(NULL),
61 long_jump_base_(NULL), 72 long_jump_base_(NULL),
62 store_buffer_block_(NULL),
63 no_callback_scope_depth_(0), 73 no_callback_scope_depth_(0),
64 #if defined(DEBUG) 74 #if defined(DEBUG)
65 top_handle_scope_(NULL), 75 top_handle_scope_(NULL),
66 no_handle_scope_depth_(0), 76 no_handle_scope_depth_(0),
67 no_safepoint_scope_depth_(0), 77 no_safepoint_scope_depth_(0),
68 #endif 78 #endif
69 reusable_handles_(), 79 reusable_handles_(),
80 saved_stack_limit_(0),
81 deferred_interrupts_mask_(0),
82 deferred_interrupts_(0),
83 stack_overflow_count_(0),
70 cha_(NULL), 84 cha_(NULL),
71 deopt_id_(0), 85 deopt_id_(0),
72 vm_tag_(0),
73 pending_functions_(GrowableObjectArray::null()), 86 pending_functions_(GrowableObjectArray::null()),
74 sticky_error_(Error::null()), 87 sticky_error_(Error::null()),
75 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_INITIALIZERS) 88 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_INITIALIZERS)
76 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_INIT) 89 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_INIT)
77 safepoint_state_(0), 90 safepoint_state_(0),
78 execution_state_(kThreadInVM), 91 execution_state_(kThreadInVM),
79 next_(NULL) { 92 next_(NULL) {
80 #define DEFAULT_INIT(type_name, member_name, init_expr, default_init_value) \ 93 #define DEFAULT_INIT(type_name, member_name, init_expr, default_init_value) \
81 member_name = default_init_value; 94 member_name = default_init_value;
82 CACHED_CONSTANTS_LIST(DEFAULT_INIT) 95 CACHED_CONSTANTS_LIST(DEFAULT_INIT)
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 // Prevent scheduling another GC by ignoring the threshold. 288 // Prevent scheduling another GC by ignoring the threshold.
276 ASSERT(store_buffer_block_ != NULL); 289 ASSERT(store_buffer_block_ != NULL);
277 StoreBufferRelease(StoreBuffer::kIgnoreThreshold); 290 StoreBufferRelease(StoreBuffer::kIgnoreThreshold);
278 // Make sure to get an *empty* block; the isolate needs all entries 291 // Make sure to get an *empty* block; the isolate needs all entries
279 // at GC time. 292 // at GC time.
280 // TODO(koda): Replace with an epilogue (PrepareAfterGC) that acquires. 293 // TODO(koda): Replace with an epilogue (PrepareAfterGC) that acquires.
281 store_buffer_block_ = isolate()->store_buffer()->PopEmptyBlock(); 294 store_buffer_block_ = isolate()->store_buffer()->PopEmptyBlock();
282 } 295 }
283 296
284 297
298 void Thread::SetStackLimitFromStackBase(uword stack_base) {
299 // Set stack limit.
300 #if defined(USING_SIMULATOR)
301 // Ignore passed-in native stack top and use Simulator stack top.
302 Simulator* sim = Simulator::Current(); // May allocate a simulator.
303 ASSERT(isolate()->simulator() == sim); // Isolate's simulator is current one.
304 stack_base = sim->StackTop();
305 // The overflow area is accounted for by the simulator.
306 #endif
307 SetStackLimit(stack_base - OSThread::GetSpecifiedStackSize());
308 }
309
310
311 void Thread::SetStackLimit(uword limit) {
312 // The thread setting the stack limit is not necessarily the thread which
313 // the stack limit is being set on.
314 MonitorLocker ml(thread_lock_);
315 if (stack_limit_ == saved_stack_limit_) {
316 // No interrupt pending, set stack_limit_ too.
317 stack_limit_ = limit;
318 }
319 saved_stack_limit_ = limit;
320 }
321
322
323 void Thread::ClearStackLimit() {
324 SetStackLimit(~static_cast<uword>(0));
325 }
326
327
328 /* static */
329 uword Thread::GetCurrentStackPointer() {
330 // Since AddressSanitizer's detect_stack_use_after_return instruments the
331 // C++ code to give out fake stack addresses, we call a stub in that case.
332 uword (*func)() = reinterpret_cast<uword (*)()>(
333 StubCode::GetStackPointer_entry()->EntryPoint());
334 // But for performance (and to support simulators), we normally use a local.
335 #if defined(__has_feature)
336 #if __has_feature(address_sanitizer)
337 uword current_sp = func();
338 return current_sp;
339 #else
340 uword stack_allocated_local_address = reinterpret_cast<uword>(&func);
341 return stack_allocated_local_address;
342 #endif
343 #else
344 uword stack_allocated_local_address = reinterpret_cast<uword>(&func);
345 return stack_allocated_local_address;
346 #endif
347 }
348
349
350 void Thread::ScheduleInterrupts(uword interrupt_bits) {
351 MonitorLocker ml(thread_lock_);
352 ScheduleInterruptsLocked(interrupt_bits);
353 }
354
355
356 void Thread::ScheduleInterruptsLocked(uword interrupt_bits) {
357 ASSERT(thread_lock_->IsOwnedByCurrentThread());
358 ASSERT((interrupt_bits & ~kInterruptsMask) == 0); // Must fit in mask.
359
360 // Check to see if any of the requested interrupts should be deferred.
361 uword defer_bits = interrupt_bits & deferred_interrupts_mask_;
362 if (defer_bits != 0) {
363 deferred_interrupts_ |= defer_bits;
364 interrupt_bits &= ~deferred_interrupts_mask_;
365 if (interrupt_bits == 0) {
366 return;
367 }
368 }
369
370 if (stack_limit_ == saved_stack_limit_) {
371 stack_limit_ = (~static_cast<uword>(0)) & ~kInterruptsMask;
372 }
373 stack_limit_ |= interrupt_bits;
374 }
375
376
377 uword Thread::GetAndClearInterrupts() {
378 MonitorLocker ml(thread_lock_);
379 if (stack_limit_ == saved_stack_limit_) {
380 return 0; // No interrupt was requested.
381 }
382 uword interrupt_bits = stack_limit_ & kInterruptsMask;
383 stack_limit_ = saved_stack_limit_;
384 return interrupt_bits;
385 }
386
387
388 void Thread::DeferOOBMessageInterrupts() {
389 MonitorLocker ml(thread_lock_);
390 ASSERT(deferred_interrupts_mask_ == 0);
391 deferred_interrupts_mask_ = kMessageInterrupt;
392
393 if (stack_limit_ != saved_stack_limit_) {
394 // Defer any interrupts which are currently pending.
395 deferred_interrupts_ = stack_limit_ & deferred_interrupts_mask_;
396
397 // Clear deferrable interrupts, if present.
398 stack_limit_ &= ~deferred_interrupts_mask_;
399
400 if ((stack_limit_ & kInterruptsMask) == 0) {
401 // No other pending interrupts. Restore normal stack limit.
402 stack_limit_ = saved_stack_limit_;
403 }
404 }
405 if (FLAG_trace_service && FLAG_trace_service_verbose) {
406 OS::Print("[+%" Pd64 "ms] Isolate %s deferring OOB interrupts\n",
407 Dart::timestamp(), isolate()->name());
408 }
409 }
410
411
412 void Thread::RestoreOOBMessageInterrupts() {
413 MonitorLocker ml(thread_lock_);
414 ASSERT(deferred_interrupts_mask_ == kMessageInterrupt);
415 deferred_interrupts_mask_ = 0;
416 if (deferred_interrupts_ != 0) {
417 if (stack_limit_ == saved_stack_limit_) {
418 stack_limit_ = (~static_cast<uword>(0)) & ~kInterruptsMask;
419 }
420 stack_limit_ |= deferred_interrupts_;
421 deferred_interrupts_ = 0;
422 }
423 if (FLAG_trace_service && FLAG_trace_service_verbose) {
424 OS::Print("[+%" Pd64 "ms] Isolate %s restoring OOB interrupts\n",
425 Dart::timestamp(), isolate()->name());
426 }
427 }
428
429
430 RawError* Thread::HandleInterrupts() {
431 uword interrupt_bits = GetAndClearInterrupts();
432 if ((interrupt_bits & kVMInterrupt) != 0) {
433 if (isolate()->store_buffer()->Overflowed()) {
434 if (FLAG_verbose_gc) {
435 OS::PrintErr("Scavenge scheduled by store buffer overflow.\n");
436 }
437 heap()->CollectGarbage(Heap::kNew);
438 }
439 }
440 if ((interrupt_bits & kMessageInterrupt) != 0) {
441 MessageHandler::MessageStatus status =
442 isolate()->message_handler()->HandleOOBMessages();
443 if (status != MessageHandler::kOK) {
444 // False result from HandleOOBMessages signals that the isolate should
445 // be terminating.
446 if (FLAG_trace_isolates) {
447 OS::Print("[!] Terminating isolate due to OOB message:\n"
448 "\tisolate: %s\n", isolate()->name());
449 }
450 Thread* thread = Thread::Current();
451 const Error& error = Error::Handle(thread->sticky_error());
452 ASSERT(!error.IsNull() && error.IsUnwindError());
453 thread->clear_sticky_error();
454 return error.raw();
455 }
456 }
457 return Error::null();
458 }
459
460
461 uword Thread::GetAndClearStackOverflowFlags() {
462 uword stack_overflow_flags = stack_overflow_flags_;
463 stack_overflow_flags_ = 0;
464 return stack_overflow_flags;
465 }
466
467
285 void Thread::StoreBufferBlockProcess(StoreBuffer::ThresholdPolicy policy) { 468 void Thread::StoreBufferBlockProcess(StoreBuffer::ThresholdPolicy policy) {
286 StoreBufferRelease(policy); 469 StoreBufferRelease(policy);
287 StoreBufferAcquire(); 470 StoreBufferAcquire();
288 } 471 }
289 472
290 473
291 void Thread::StoreBufferAddObject(RawObject* obj) { 474 void Thread::StoreBufferAddObject(RawObject* obj) {
292 store_buffer_block_->Push(obj); 475 store_buffer_block_->Push(obj);
293 if (store_buffer_block_->IsFull()) { 476 if (store_buffer_block_->IsFull()) {
294 StoreBufferBlockProcess(StoreBuffer::kCheckThreshold); 477 StoreBufferBlockProcess(StoreBuffer::kCheckThreshold);
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 687
505 DisableThreadInterruptsScope::~DisableThreadInterruptsScope() { 688 DisableThreadInterruptsScope::~DisableThreadInterruptsScope() {
506 if (thread() != NULL) { 689 if (thread() != NULL) {
507 OSThread* os_thread = thread()->os_thread(); 690 OSThread* os_thread = thread()->os_thread();
508 ASSERT(os_thread != NULL); 691 ASSERT(os_thread != NULL);
509 os_thread->EnableThreadInterrupts(); 692 os_thread->EnableThreadInterrupts();
510 } 693 }
511 } 694 }
512 695
513 } // namespace dart 696 } // namespace dart
OLDNEW
« runtime/vm/intermediate_language_arm.cc ('K') | « runtime/vm/thread.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698