OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/isolate.h" | 5 #include "vm/isolate.h" |
6 | 6 |
7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 #include "include/dart_native_api.h" | 8 #include "include/dart_native_api.h" |
9 #include "platform/assert.h" | 9 #include "platform/assert.h" |
10 #include "platform/text_buffer.h" | 10 #include "platform/text_buffer.h" |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 return new Message(dest_port, obj.raw(), Message::kNormalPriority); | 147 return new Message(dest_port, obj.raw(), Message::kNormalPriority); |
148 } else { | 148 } else { |
149 uint8_t* obj_data; | 149 uint8_t* obj_data; |
150 intptr_t obj_len; | 150 intptr_t obj_len; |
151 SerializeObject(obj, &obj_data, &obj_len, false); | 151 SerializeObject(obj, &obj_data, &obj_len, false); |
152 return new Message(dest_port, obj_data, obj_len, Message::kNormalPriority); | 152 return new Message(dest_port, obj_data, obj_len, Message::kNormalPriority); |
153 } | 153 } |
154 } | 154 } |
155 | 155 |
156 | 156 |
| 157 NoOOBMessageScope::NoOOBMessageScope(Thread* thread) : StackResource(thread) { |
| 158 isolate()->DeferOOBMessageInterrupts(); |
| 159 } |
| 160 |
| 161 |
| 162 NoOOBMessageScope::~NoOOBMessageScope() { |
| 163 isolate()->RestoreOOBMessageInterrupts(); |
| 164 } |
| 165 |
| 166 |
| 167 |
157 void Isolate::RegisterClass(const Class& cls) { | 168 void Isolate::RegisterClass(const Class& cls) { |
158 class_table()->Register(cls); | 169 class_table()->Register(cls); |
159 } | 170 } |
160 | 171 |
161 | 172 |
162 void Isolate::RegisterClassAt(intptr_t index, const Class& cls) { | 173 void Isolate::RegisterClassAt(intptr_t index, const Class& cls) { |
163 class_table()->RegisterAt(index, cls); | 174 class_table()->RegisterAt(index, cls); |
164 } | 175 } |
165 | 176 |
166 | 177 |
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
781 api_state_(NULL), | 792 api_state_(NULL), |
782 debugger_(NULL), | 793 debugger_(NULL), |
783 resume_request_(false), | 794 resume_request_(false), |
784 last_resume_timestamp_(OS::GetCurrentTimeMillis()), | 795 last_resume_timestamp_(OS::GetCurrentTimeMillis()), |
785 has_compiled_code_(false), | 796 has_compiled_code_(false), |
786 flags_(), | 797 flags_(), |
787 random_(), | 798 random_(), |
788 simulator_(NULL), | 799 simulator_(NULL), |
789 mutex_(new Mutex()), | 800 mutex_(new Mutex()), |
790 saved_stack_limit_(0), | 801 saved_stack_limit_(0), |
| 802 deferred_interrupts_mask_(0), |
| 803 deferred_interrupts_(0), |
791 stack_overflow_flags_(0), | 804 stack_overflow_flags_(0), |
792 stack_overflow_count_(0), | 805 stack_overflow_count_(0), |
793 message_handler_(NULL), | 806 message_handler_(NULL), |
794 spawn_state_(NULL), | 807 spawn_state_(NULL), |
795 is_runnable_(false), | 808 is_runnable_(false), |
796 gc_prologue_callback_(NULL), | 809 gc_prologue_callback_(NULL), |
797 gc_epilogue_callback_(NULL), | 810 gc_epilogue_callback_(NULL), |
798 defer_finalization_count_(0), | 811 defer_finalization_count_(0), |
799 deopt_context_(NULL), | 812 deopt_context_(NULL), |
800 compiler_stats_(NULL), | 813 compiler_stats_(NULL), |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1046 } | 1059 } |
1047 saved_stack_limit_ = limit; | 1060 saved_stack_limit_ = limit; |
1048 } | 1061 } |
1049 | 1062 |
1050 | 1063 |
1051 void Isolate::ClearStackLimit() { | 1064 void Isolate::ClearStackLimit() { |
1052 SetStackLimit(~static_cast<uword>(0)); | 1065 SetStackLimit(~static_cast<uword>(0)); |
1053 } | 1066 } |
1054 | 1067 |
1055 | 1068 |
1056 void Isolate::ScheduleInterrupts(uword interrupt_bits) { | |
1057 MutexLocker ml(mutex_); | |
1058 ASSERT((interrupt_bits & ~kInterruptsMask) == 0); // Must fit in mask. | |
1059 if (stack_limit_ == saved_stack_limit_) { | |
1060 stack_limit_ = (~static_cast<uword>(0)) & ~kInterruptsMask; | |
1061 } | |
1062 stack_limit_ |= interrupt_bits; | |
1063 } | |
1064 | |
1065 | |
1066 void Isolate::DoneLoading() { | 1069 void Isolate::DoneLoading() { |
1067 GrowableObjectArray& libs = GrowableObjectArray::Handle(current_zone(), | 1070 GrowableObjectArray& libs = GrowableObjectArray::Handle(current_zone(), |
1068 object_store()->libraries()); | 1071 object_store()->libraries()); |
1069 Library& lib = Library::Handle(current_zone()); | 1072 Library& lib = Library::Handle(current_zone()); |
1070 intptr_t num_libs = libs.Length(); | 1073 intptr_t num_libs = libs.Length(); |
1071 for (intptr_t i = 0; i < num_libs; i++) { | 1074 for (intptr_t i = 0; i < num_libs; i++) { |
1072 lib ^= libs.At(i); | 1075 lib ^= libs.At(i); |
1073 // If this library was loaded with Dart_LoadLibrary, it was marked | 1076 // If this library was loaded with Dart_LoadLibrary, it was marked |
1074 // as 'load in progres'. Set the status to 'loaded'. | 1077 // as 'load in progres'. Set the status to 'loaded'. |
1075 if (lib.LoadInProgress()) { | 1078 if (lib.LoadInProgress()) { |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1459 | 1462 |
1460 | 1463 |
1461 void Isolate::Run() { | 1464 void Isolate::Run() { |
1462 message_handler()->Run(Dart::thread_pool(), | 1465 message_handler()->Run(Dart::thread_pool(), |
1463 RunIsolate, | 1466 RunIsolate, |
1464 ShutdownIsolate, | 1467 ShutdownIsolate, |
1465 reinterpret_cast<uword>(this)); | 1468 reinterpret_cast<uword>(this)); |
1466 } | 1469 } |
1467 | 1470 |
1468 | 1471 |
| 1472 void Isolate::ScheduleInterrupts(uword interrupt_bits) { |
| 1473 MutexLocker ml(mutex_); |
| 1474 ASSERT((interrupt_bits & ~kInterruptsMask) == 0); // Must fit in mask. |
| 1475 |
| 1476 // Check to see if any of the requested interrupts should be deferred. |
| 1477 uword defer_bits = interrupt_bits & deferred_interrupts_mask_; |
| 1478 if (defer_bits != 0) { |
| 1479 deferred_interrupts_ |= defer_bits; |
| 1480 interrupt_bits &= ~deferred_interrupts_mask_; |
| 1481 if (interrupt_bits == 0) { |
| 1482 return; |
| 1483 } |
| 1484 } |
| 1485 |
| 1486 if (stack_limit_ == saved_stack_limit_) { |
| 1487 stack_limit_ = (~static_cast<uword>(0)) & ~kInterruptsMask; |
| 1488 } |
| 1489 stack_limit_ |= interrupt_bits; |
| 1490 } |
| 1491 |
| 1492 |
1469 uword Isolate::GetAndClearInterrupts() { | 1493 uword Isolate::GetAndClearInterrupts() { |
1470 MutexLocker ml(mutex_); | 1494 MutexLocker ml(mutex_); |
1471 if (stack_limit_ == saved_stack_limit_) { | 1495 if (stack_limit_ == saved_stack_limit_) { |
1472 return 0; // No interrupt was requested. | 1496 return 0; // No interrupt was requested. |
1473 } | 1497 } |
1474 uword interrupt_bits = stack_limit_ & kInterruptsMask; | 1498 uword interrupt_bits = stack_limit_ & kInterruptsMask; |
1475 stack_limit_ = saved_stack_limit_; | 1499 stack_limit_ = saved_stack_limit_; |
1476 return interrupt_bits; | 1500 return interrupt_bits; |
1477 } | 1501 } |
1478 | 1502 |
1479 | 1503 |
| 1504 void Isolate::DeferOOBMessageInterrupts() { |
| 1505 MutexLocker ml(mutex_); |
| 1506 ASSERT(deferred_interrupts_mask_ == 0); |
| 1507 deferred_interrupts_mask_ = kMessageInterrupt; |
| 1508 |
| 1509 if (stack_limit_ != saved_stack_limit_) { |
| 1510 // Defer any interrupts which are currently pending. |
| 1511 deferred_interrupts_ = stack_limit_ & deferred_interrupts_mask_; |
| 1512 |
| 1513 // Clear deferrable interrupts, if present. |
| 1514 stack_limit_ &= ~deferred_interrupts_mask_; |
| 1515 |
| 1516 if ((stack_limit_ & kInterruptsMask) == 0) { |
| 1517 // No other pending interrupts. Restore normal stack limit. |
| 1518 stack_limit_ = saved_stack_limit_; |
| 1519 } |
| 1520 } |
| 1521 } |
| 1522 |
| 1523 |
| 1524 void Isolate::RestoreOOBMessageInterrupts() { |
| 1525 MutexLocker ml(mutex_); |
| 1526 ASSERT(deferred_interrupts_mask_ == kMessageInterrupt); |
| 1527 deferred_interrupts_mask_ = 0; |
| 1528 if (deferred_interrupts_ != 0) { |
| 1529 if (stack_limit_ == saved_stack_limit_) { |
| 1530 stack_limit_ = (~static_cast<uword>(0)) & ~kInterruptsMask; |
| 1531 } |
| 1532 stack_limit_ |= deferred_interrupts_; |
| 1533 deferred_interrupts_ = 0; |
| 1534 } |
| 1535 } |
| 1536 |
| 1537 |
1480 RawError* Isolate::HandleInterrupts() { | 1538 RawError* Isolate::HandleInterrupts() { |
1481 uword interrupt_bits = GetAndClearInterrupts(); | 1539 uword interrupt_bits = GetAndClearInterrupts(); |
1482 if ((interrupt_bits & kVMInterrupt) != 0) { | 1540 if ((interrupt_bits & kVMInterrupt) != 0) { |
1483 if (store_buffer()->Overflowed()) { | 1541 if (store_buffer()->Overflowed()) { |
1484 if (FLAG_verbose_gc) { | 1542 if (FLAG_verbose_gc) { |
1485 OS::PrintErr("Scavenge scheduled by store buffer overflow.\n"); | 1543 OS::PrintErr("Scavenge scheduled by store buffer overflow.\n"); |
1486 } | 1544 } |
1487 heap()->CollectGarbage(Heap::kNew); | 1545 heap()->CollectGarbage(Heap::kNew); |
1488 } | 1546 } |
1489 } | 1547 } |
(...skipping 1190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2680 void IsolateSpawnState::DecrementSpawnCount() { | 2738 void IsolateSpawnState::DecrementSpawnCount() { |
2681 ASSERT(spawn_count_monitor_ != NULL); | 2739 ASSERT(spawn_count_monitor_ != NULL); |
2682 ASSERT(spawn_count_ != NULL); | 2740 ASSERT(spawn_count_ != NULL); |
2683 MonitorLocker ml(spawn_count_monitor_); | 2741 MonitorLocker ml(spawn_count_monitor_); |
2684 ASSERT(*spawn_count_ > 0); | 2742 ASSERT(*spawn_count_ > 0); |
2685 *spawn_count_ = *spawn_count_ - 1; | 2743 *spawn_count_ = *spawn_count_ - 1; |
2686 ml.Notify(); | 2744 ml.Notify(); |
2687 } | 2745 } |
2688 | 2746 |
2689 } // namespace dart | 2747 } // namespace dart |
OLD | NEW |