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/dart_api_state.h" |
7 #include "vm/growable_array.h" | 8 #include "vm/growable_array.h" |
8 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
9 #include "vm/lockers.h" | 10 #include "vm/lockers.h" |
10 #include "vm/log.h" | 11 #include "vm/log.h" |
11 #include "vm/native_entry.h" | 12 #include "vm/native_entry.h" |
12 #include "vm/object.h" | 13 #include "vm/object.h" |
13 #include "vm/os_thread.h" | 14 #include "vm/os_thread.h" |
14 #include "vm/profiler.h" | 15 #include "vm/profiler.h" |
15 #include "vm/runtime_entry.h" | 16 #include "vm/runtime_entry.h" |
16 #include "vm/stub_code.h" | 17 #include "vm/stub_code.h" |
(...skipping 19 matching lines...) Expand all Loading... |
36 #define REUSABLE_HANDLE_INITIALIZERS(object) \ | 37 #define REUSABLE_HANDLE_INITIALIZERS(object) \ |
37 object##_handle_(NULL), | 38 object##_handle_(NULL), |
38 | 39 |
39 | 40 |
40 Thread::Thread(Isolate* isolate) | 41 Thread::Thread(Isolate* isolate) |
41 : BaseThread(false), | 42 : BaseThread(false), |
42 os_thread_(NULL), | 43 os_thread_(NULL), |
43 isolate_(NULL), | 44 isolate_(NULL), |
44 heap_(NULL), | 45 heap_(NULL), |
45 zone_(NULL), | 46 zone_(NULL), |
| 47 api_reusable_scope_(NULL), |
| 48 api_top_scope_(NULL), |
46 top_exit_frame_info_(0), | 49 top_exit_frame_info_(0), |
47 top_resource_(NULL), | 50 top_resource_(NULL), |
48 long_jump_base_(NULL), | 51 long_jump_base_(NULL), |
49 store_buffer_block_(NULL), | 52 store_buffer_block_(NULL), |
50 no_callback_scope_depth_(0), | 53 no_callback_scope_depth_(0), |
51 #if defined(DEBUG) | 54 #if defined(DEBUG) |
52 top_handle_scope_(NULL), | 55 top_handle_scope_(NULL), |
53 no_handle_scope_depth_(0), | 56 no_handle_scope_depth_(0), |
54 no_safepoint_scope_depth_(0), | 57 no_safepoint_scope_depth_(0), |
55 #endif | 58 #endif |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 #undef CLEAR_REUSABLE_HANDLE | 270 #undef CLEAR_REUSABLE_HANDLE |
268 } | 271 } |
269 | 272 |
270 | 273 |
271 void Thread::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 274 void Thread::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
272 ASSERT(visitor != NULL); | 275 ASSERT(visitor != NULL); |
273 | 276 |
274 // Visit objects in thread specific handles area. | 277 // Visit objects in thread specific handles area. |
275 reusable_handles_.VisitObjectPointers(visitor); | 278 reusable_handles_.VisitObjectPointers(visitor); |
276 | 279 |
| 280 // Visit the pending functions. |
277 if (pending_functions_ != GrowableObjectArray::null()) { | 281 if (pending_functions_ != GrowableObjectArray::null()) { |
278 visitor->VisitPointer( | 282 visitor->VisitPointer( |
279 reinterpret_cast<RawObject**>(&pending_functions_)); | 283 reinterpret_cast<RawObject**>(&pending_functions_)); |
280 } | 284 } |
| 285 |
| 286 // Visit the api local scope as it has all the api local handles. |
| 287 ApiLocalScope* scope = api_top_scope_; |
| 288 while (scope != NULL) { |
| 289 scope->local_handles()->VisitObjectPointers(visitor); |
| 290 scope = scope->previous(); |
| 291 } |
281 } | 292 } |
282 | 293 |
283 | 294 |
284 bool Thread::CanLoadFromThread(const Object& object) { | 295 bool Thread::CanLoadFromThread(const Object& object) { |
285 #define CHECK_OBJECT(type_name, member_name, expr, default_init_value) \ | 296 #define CHECK_OBJECT(type_name, member_name, expr, default_init_value) \ |
286 if (object.raw() == expr) return true; | 297 if (object.raw() == expr) return true; |
287 CACHED_VM_OBJECTS_LIST(CHECK_OBJECT) | 298 CACHED_VM_OBJECTS_LIST(CHECK_OBJECT) |
288 #undef CHECK_OBJECT | 299 #undef CHECK_OBJECT |
289 return false; | 300 return false; |
290 } | 301 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 return Thread::name##_entry_point_offset(); \ | 337 return Thread::name##_entry_point_offset(); \ |
327 } | 338 } |
328 LEAF_RUNTIME_ENTRY_LIST(COMPUTE_OFFSET) | 339 LEAF_RUNTIME_ENTRY_LIST(COMPUTE_OFFSET) |
329 #undef COMPUTE_OFFSET | 340 #undef COMPUTE_OFFSET |
330 | 341 |
331 UNREACHABLE(); | 342 UNREACHABLE(); |
332 return -1; | 343 return -1; |
333 } | 344 } |
334 | 345 |
335 | 346 |
| 347 bool Thread::IsValidLocalHandle(Dart_Handle object) const { |
| 348 ApiLocalScope* scope = api_top_scope_; |
| 349 while (scope != NULL) { |
| 350 if (scope->local_handles()->IsValidHandle(object)) { |
| 351 return true; |
| 352 } |
| 353 scope = scope->previous(); |
| 354 } |
| 355 return false; |
| 356 } |
| 357 |
| 358 |
| 359 int Thread::CountLocalHandles() const { |
| 360 int total = 0; |
| 361 ApiLocalScope* scope = api_top_scope_; |
| 362 while (scope != NULL) { |
| 363 total += scope->local_handles()->CountHandles(); |
| 364 scope = scope->previous(); |
| 365 } |
| 366 return total; |
| 367 } |
| 368 |
| 369 |
| 370 int Thread::ZoneSizeInBytes() const { |
| 371 int total = 0; |
| 372 ApiLocalScope* scope = api_top_scope_; |
| 373 while (scope != NULL) { |
| 374 total += scope->zone()->SizeInBytes(); |
| 375 scope = scope->previous(); |
| 376 } |
| 377 return total; |
| 378 } |
| 379 |
| 380 |
| 381 void Thread::UnwindScopes(uword stack_marker) { |
| 382 // Unwind all scopes using the same stack_marker, i.e. all scopes allocated |
| 383 // under the same top_exit_frame_info. |
| 384 ApiLocalScope* scope = api_top_scope_; |
| 385 while (scope != NULL && |
| 386 scope->stack_marker() != 0 && |
| 387 scope->stack_marker() == stack_marker) { |
| 388 api_top_scope_ = scope->previous(); |
| 389 delete scope; |
| 390 scope = api_top_scope_; |
| 391 } |
| 392 } |
| 393 |
| 394 |
336 DisableThreadInterruptsScope::DisableThreadInterruptsScope(Thread* thread) | 395 DisableThreadInterruptsScope::DisableThreadInterruptsScope(Thread* thread) |
337 : StackResource(thread) { | 396 : StackResource(thread) { |
338 if (thread != NULL) { | 397 if (thread != NULL) { |
339 OSThread* os_thread = thread->os_thread(); | 398 OSThread* os_thread = thread->os_thread(); |
340 ASSERT(os_thread != NULL); | 399 ASSERT(os_thread != NULL); |
341 os_thread->DisableThreadInterrupts(); | 400 os_thread->DisableThreadInterrupts(); |
342 } | 401 } |
343 } | 402 } |
344 | 403 |
345 | 404 |
346 DisableThreadInterruptsScope::~DisableThreadInterruptsScope() { | 405 DisableThreadInterruptsScope::~DisableThreadInterruptsScope() { |
347 if (thread() != NULL) { | 406 if (thread() != NULL) { |
348 OSThread* os_thread = thread()->os_thread(); | 407 OSThread* os_thread = thread()->os_thread(); |
349 ASSERT(os_thread != NULL); | 408 ASSERT(os_thread != NULL); |
350 os_thread->EnableThreadInterrupts(); | 409 os_thread->EnableThreadInterrupts(); |
351 } | 410 } |
352 } | 411 } |
353 | 412 |
354 } // namespace dart | 413 } // namespace dart |
OLD | NEW |