-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
isolate.h
1215 lines (1008 loc) · 40.2 KB
/
isolate.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#ifndef RUNTIME_VM_ISOLATE_H_
#define RUNTIME_VM_ISOLATE_H_
#if defined(SHOULD_NOT_INCLUDE_RUNTIME)
#error "Should not include runtime"
#endif
#include "include/dart_api.h"
#include "platform/assert.h"
#include "platform/atomic.h"
#include "vm/base_isolate.h"
#include "vm/class_table.h"
#include "vm/exceptions.h"
#include "vm/fixed_cache.h"
#include "vm/growable_array.h"
#include "vm/handles.h"
#include "vm/heap/verifier.h"
#include "vm/megamorphic_cache_table.h"
#include "vm/metrics.h"
#include "vm/os_thread.h"
#include "vm/random.h"
#include "vm/tags.h"
#include "vm/thread.h"
#include "vm/thread_stack_resource.h"
#include "vm/token_position.h"
namespace dart {
// Forward declarations.
class ApiState;
class BackgroundCompiler;
class Capability;
class CodeIndexTable;
class Debugger;
class DeoptContext;
class ExternalTypedData;
class HandleScope;
class HandleVisitor;
class Heap;
class ICData;
#if !defined(DART_PRECOMPILED_RUNTIME)
class Interpreter;
#endif
class IsolateProfilerData;
class IsolateReloadContext;
class IsolateSpawnState;
class Log;
class Message;
class MessageHandler;
class Mutex;
class Object;
class ObjectIdRing;
class ObjectPointerVisitor;
class ObjectStore;
class RawInstance;
class RawArray;
class RawContext;
class RawDouble;
class RawError;
class RawField;
class RawGrowableObjectArray;
class RawMint;
class RawObject;
class RawInteger;
class RawFloat32x4;
class RawInt32x4;
class RawUserTag;
class ReversePcLookupCache;
class SafepointHandler;
class SampleBuffer;
class SendPort;
class SerializedObjectBuffer;
class ServiceIdZone;
class Simulator;
class StackResource;
class StackZone;
class StoreBuffer;
class StubCode;
class ThreadRegistry;
class UserTag;
class PendingLazyDeopt {
public:
PendingLazyDeopt(uword fp, uword pc) : fp_(fp), pc_(pc) {}
uword fp() { return fp_; }
uword pc() { return pc_; }
void set_pc(uword pc) { pc_ = pc; }
private:
uword fp_;
uword pc_;
};
class IsolateVisitor {
public:
IsolateVisitor() {}
virtual ~IsolateVisitor() {}
virtual void VisitIsolate(Isolate* isolate) = 0;
protected:
// Returns true if |isolate| is the VM or service isolate.
bool IsVMInternalIsolate(Isolate* isolate) const;
private:
DISALLOW_COPY_AND_ASSIGN(IsolateVisitor);
};
// Disallow OOB message handling within this scope.
class NoOOBMessageScope : public ThreadStackResource {
public:
explicit NoOOBMessageScope(Thread* thread);
~NoOOBMessageScope();
private:
DISALLOW_COPY_AND_ASSIGN(NoOOBMessageScope);
};
// Disallow isolate reload.
class NoReloadScope : public ThreadStackResource {
public:
NoReloadScope(Isolate* isolate, Thread* thread);
~NoReloadScope();
private:
Isolate* isolate_;
DISALLOW_COPY_AND_ASSIGN(NoReloadScope);
};
// Fixed cache for exception handler lookup.
typedef FixedCache<intptr_t, ExceptionHandlerInfo, 16> HandlerInfoCache;
// Fixed cache for catch entry state lookup.
typedef FixedCache<intptr_t, CatchEntryMovesRefPtr, 16> CatchEntryMovesCache;
// List of Isolate flags with corresponding members of Dart_IsolateFlags and
// corresponding global command line flags.
//
// V(when, name, bit-name, Dart_IsolateFlags-name, command-line-flag-name)
//
#define ISOLATE_FLAG_LIST(V) \
V(NONPRODUCT, asserts, EnableAsserts, enable_asserts, FLAG_enable_asserts) \
V(NONPRODUCT, use_field_guards, UseFieldGuards, use_field_guards, \
FLAG_use_field_guards) \
V(NONPRODUCT, use_osr, UseOsr, use_osr, FLAG_use_osr) \
V(PRECOMPILER, obfuscate, Obfuscate, obfuscate, false_by_default) \
V(PRODUCT, unsafe_trust_strong_mode_types, UnsafeTrustStrongModeTypes, \
unsafe_trust_strong_mode_types, \
FLAG_experimental_unsafe_mode_use_at_your_own_risk)
class Isolate : public BaseIsolate {
public:
// Keep both these enums in sync with isolate_patch.dart.
// The different Isolate API message types.
enum LibMsgId {
kPauseMsg = 1,
kResumeMsg = 2,
kPingMsg = 3,
kKillMsg = 4,
kAddExitMsg = 5,
kDelExitMsg = 6,
kAddErrorMsg = 7,
kDelErrorMsg = 8,
kErrorFatalMsg = 9,
// Internal message ids.
kInterruptMsg = 10, // Break in the debugger.
kInternalKillMsg = 11, // Like kill, but does not run exit listeners, etc.
kLowMemoryMsg = 12, // Run compactor, etc.
kDrainServiceExtensionsMsg = 13, // Invoke pending service extensions
};
// The different Isolate API message priorities for ping and kill messages.
enum LibMsgPriority {
kImmediateAction = 0,
kBeforeNextEventAction = 1,
kAsEventAction = 2
};
~Isolate();
static inline Isolate* Current() {
Thread* thread = Thread::Current();
return thread == NULL ? NULL : thread->isolate();
}
// Register a newly introduced class.
void RegisterClass(const Class& cls);
#if defined(DEBUG)
void ValidateClassTable();
#endif
void RehashConstants();
#if defined(DEBUG)
void ValidateConstants();
#endif
// Visits weak object pointers.
void VisitWeakPersistentHandles(HandleVisitor* visitor);
// Prepares all threads in an isolate for Garbage Collection.
void ReleaseStoreBuffers();
void EnableIncrementalBarrier(MarkingStack* marking_stack,
MarkingStack* deferred_marking_stack);
void DisableIncrementalBarrier();
StoreBuffer* store_buffer() const { return store_buffer_; }
MarkingStack* marking_stack() const { return marking_stack_; }
MarkingStack* deferred_marking_stack() const {
return deferred_marking_stack_;
}
ThreadRegistry* thread_registry() const { return thread_registry_; }
SafepointHandler* safepoint_handler() const { return safepoint_handler_; }
ClassTable* class_table() { return &class_table_; }
static intptr_t class_table_offset() {
return OFFSET_OF(Isolate, class_table_);
}
// Prefers old classes when we are in the middle of a reload.
RawClass* GetClassForHeapWalkAt(intptr_t cid);
intptr_t GetClassSizeForHeapWalkAt(intptr_t cid);
static intptr_t ic_miss_code_offset() {
return OFFSET_OF(Isolate, ic_miss_code_);
}
Dart_MessageNotifyCallback message_notify_callback() const {
return message_notify_callback_;
}
void set_message_notify_callback(Dart_MessageNotifyCallback value) {
message_notify_callback_ = value;
}
bool HasPendingMessages();
Thread* mutator_thread() const;
const char* name() const { return name_; }
void set_name(const char* name);
int64_t UptimeMicros() const;
Dart_Port main_port() const { return main_port_; }
void set_main_port(Dart_Port port) {
ASSERT(main_port_ == 0); // Only set main port once.
main_port_ = port;
}
Dart_Port origin_id() const { return origin_id_; }
void set_origin_id(Dart_Port id) {
ASSERT((id == main_port_ && origin_id_ == 0) || (origin_id_ == main_port_));
origin_id_ = id;
}
void set_pause_capability(uint64_t value) { pause_capability_ = value; }
uint64_t pause_capability() const { return pause_capability_; }
void set_terminate_capability(uint64_t value) {
terminate_capability_ = value;
}
uint64_t terminate_capability() const { return terminate_capability_; }
void SendInternalLibMessage(LibMsgId msg_id, uint64_t capability);
Heap* heap() const { return heap_; }
void set_heap(Heap* value) { heap_ = value; }
ObjectStore* object_store() const { return object_store_; }
void set_object_store(ObjectStore* value) { object_store_ = value; }
static intptr_t object_store_offset() {
return OFFSET_OF(Isolate, object_store_);
}
ApiState* api_state() const { return api_state_; }
void set_api_state(ApiState* value) { api_state_ = value; }
void set_init_callback_data(void* value) { init_callback_data_ = value; }
void* init_callback_data() const { return init_callback_data_; }
Dart_EnvironmentCallback environment_callback() const {
return environment_callback_;
}
void set_environment_callback(Dart_EnvironmentCallback value) {
environment_callback_ = value;
}
bool HasTagHandler() const { return library_tag_handler_ != nullptr; }
RawObject* CallTagHandler(Dart_LibraryTag tag,
const Object& arg1,
const Object& arg2);
void set_library_tag_handler(Dart_LibraryTagHandler value) {
library_tag_handler_ = value;
}
void SetupImagePage(const uint8_t* snapshot_buffer, bool is_executable);
void ScheduleInterrupts(uword interrupt_bits);
// Marks all libraries as loaded.
void DoneLoading();
void DoneFinalizing();
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
// By default the reload context is deleted. This parameter allows
// the caller to delete is separately if it is still needed.
bool ReloadSources(JSONStream* js,
bool force_reload,
const char* root_script_url = NULL,
const char* packages_url = NULL,
bool dont_delete_reload_context = false);
// If provided, the VM takes ownership of kernel_buffer.
bool ReloadKernel(JSONStream* js,
bool force_reload,
const uint8_t* kernel_buffer = NULL,
intptr_t kernel_buffer_size = 0,
bool dont_delete_reload_context = false);
#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
const char* MakeRunnable();
void Run();
MessageHandler* message_handler() const { return message_handler_; }
void set_message_handler(MessageHandler* value) { message_handler_ = value; }
bool is_runnable() const { return IsRunnableBit::decode(isolate_flags_); }
void set_is_runnable(bool value) {
isolate_flags_ = IsRunnableBit::update(value, isolate_flags_);
#if !defined(PRODUCT)
if (is_runnable()) {
set_last_resume_timestamp();
}
#endif
}
void NotifyIdle(int64_t deadline);
bool compaction_in_progress() const {
return CompactionInProgressBit::decode(isolate_flags_);
}
void set_compaction_in_progress(bool value) {
isolate_flags_ = CompactionInProgressBit::update(value, isolate_flags_);
}
IsolateSpawnState* spawn_state() const { return spawn_state_; }
void set_spawn_state(IsolateSpawnState* value) { spawn_state_ = value; }
Mutex* mutex() const { return mutex_; }
Mutex* symbols_mutex() const { return symbols_mutex_; }
Mutex* type_canonicalization_mutex() const {
return type_canonicalization_mutex_;
}
Mutex* constant_canonicalization_mutex() const {
return constant_canonicalization_mutex_;
}
Mutex* megamorphic_lookup_mutex() const { return megamorphic_lookup_mutex_; }
Mutex* kernel_data_lib_cache_mutex() const {
return kernel_data_lib_cache_mutex_;
}
Mutex* kernel_data_class_cache_mutex() const {
return kernel_data_class_cache_mutex_;
}
// Any access to constants arrays must be locked since mutator and
// background compiler can access the arrays at the same time.
Mutex* kernel_constants_mutex() const { return kernel_constants_mutex_; }
#if !defined(PRODUCT)
Debugger* debugger() const {
ASSERT(debugger_ != NULL);
return debugger_;
}
void set_single_step(bool value) { single_step_ = value; }
bool single_step() const { return single_step_; }
static intptr_t single_step_offset() {
return OFFSET_OF(Isolate, single_step_);
}
bool ResumeRequest() const {
return ResumeRequestBit::decode(isolate_flags_);
}
// Lets the embedder know that a service message resulted in a resume request.
void SetResumeRequest() {
isolate_flags_ = ResumeRequestBit::update(true, isolate_flags_);
set_last_resume_timestamp();
}
void set_last_resume_timestamp() {
last_resume_timestamp_ = OS::GetCurrentTimeMillis();
}
int64_t last_resume_timestamp() const { return last_resume_timestamp_; }
// Returns whether the vm service has requested that the debugger
// resume execution.
bool GetAndClearResumeRequest() {
bool resume_request = ResumeRequestBit::decode(isolate_flags_);
isolate_flags_ = ResumeRequestBit::update(false, isolate_flags_);
return resume_request;
}
#endif
// Verify that the sender has the capability to pause or terminate the
// isolate.
bool VerifyPauseCapability(const Object& capability) const;
bool VerifyTerminateCapability(const Object& capability) const;
// Returns true if the capability was added or removed from this isolate's
// list of pause events.
bool AddResumeCapability(const Capability& capability);
bool RemoveResumeCapability(const Capability& capability);
void AddExitListener(const SendPort& listener, const Instance& response);
void RemoveExitListener(const SendPort& listener);
void NotifyExitListeners();
void AddErrorListener(const SendPort& listener);
void RemoveErrorListener(const SendPort& listener);
bool NotifyErrorListeners(const String& msg, const String& stacktrace);
bool ErrorsFatal() const { return ErrorsFatalBit::decode(isolate_flags_); }
void SetErrorsFatal(bool val) {
isolate_flags_ = ErrorsFatalBit::update(val, isolate_flags_);
}
Random* random() { return &random_; }
Simulator* simulator() const { return simulator_; }
void set_simulator(Simulator* value) { simulator_ = value; }
Monitor* spawn_count_monitor() const { return spawn_count_monitor_; }
intptr_t* spawn_count() { return &spawn_count_; }
void IncrementSpawnCount();
void WaitForOutstandingSpawns();
static void SetCreateCallback(Dart_IsolateCreateCallback cb) {
create_callback_ = cb;
}
static Dart_IsolateCreateCallback CreateCallback() {
return create_callback_;
}
static void SetShutdownCallback(Dart_IsolateShutdownCallback cb) {
shutdown_callback_ = cb;
}
static Dart_IsolateShutdownCallback ShutdownCallback() {
return shutdown_callback_;
}
static void SetCleanupCallback(Dart_IsolateCleanupCallback cb) {
cleanup_callback_ = cb;
}
static Dart_IsolateCleanupCallback CleanupCallback() {
return cleanup_callback_;
}
#if !defined(PRODUCT)
void set_object_id_ring(ObjectIdRing* ring) { object_id_ring_ = ring; }
ObjectIdRing* object_id_ring() { return object_id_ring_; }
#endif // !defined(PRODUCT)
void AddPendingDeopt(uword fp, uword pc);
uword FindPendingDeopt(uword fp) const;
void ClearPendingDeoptsAtOrBelow(uword fp) const;
MallocGrowableArray<PendingLazyDeopt>* pending_deopts() const {
return pending_deopts_;
}
bool IsDeoptimizing() const { return deopt_context_ != NULL; }
DeoptContext* deopt_context() const { return deopt_context_; }
void set_deopt_context(DeoptContext* value) {
ASSERT(value == NULL || deopt_context_ == NULL);
deopt_context_ = value;
}
BackgroundCompiler* background_compiler() const {
return background_compiler_;
}
BackgroundCompiler* optimizing_background_compiler() const {
return optimizing_background_compiler_;
}
#if !defined(PRODUCT)
void UpdateLastAllocationProfileAccumulatorResetTimestamp() {
last_allocationprofile_accumulator_reset_timestamp_ =
OS::GetCurrentTimeMillis();
}
int64_t last_allocationprofile_accumulator_reset_timestamp() const {
return last_allocationprofile_accumulator_reset_timestamp_;
}
void UpdateLastAllocationProfileGCTimestamp() {
last_allocationprofile_gc_timestamp_ = OS::GetCurrentTimeMillis();
}
int64_t last_allocationprofile_gc_timestamp() const {
return last_allocationprofile_gc_timestamp_;
}
#endif // !defined(PRODUCT)
intptr_t BlockClassFinalization() {
ASSERT(defer_finalization_count_ >= 0);
return defer_finalization_count_++;
}
intptr_t UnblockClassFinalization() {
ASSERT(defer_finalization_count_ > 0);
return defer_finalization_count_--;
}
bool AllowClassFinalization() {
ASSERT(defer_finalization_count_ >= 0);
return defer_finalization_count_ == 0;
}
#ifndef PRODUCT
void PrintJSON(JSONStream* stream, bool ref = true);
// Creates an object with the total heap memory usage statistics for this
// isolate.
void PrintMemoryUsageJSON(JSONStream* stream);
#endif
#if !defined(PRODUCT)
VMTagCounters* vm_tag_counters() { return &vm_tag_counters_; }
#if !defined(DART_PRECOMPILED_RUNTIME)
bool IsReloading() const { return reload_context_ != NULL; }
IsolateReloadContext* reload_context() { return reload_context_; }
void DeleteReloadContext();
bool HasAttemptedReload() const {
return HasAttemptedReloadBit::decode(isolate_flags_);
}
void SetHasAttemptedReload(bool value) {
isolate_flags_ = HasAttemptedReloadBit::update(value, isolate_flags_);
}
bool CanReload() const;
void set_last_reload_timestamp(int64_t value) {
last_reload_timestamp_ = value;
}
int64_t last_reload_timestamp() const { return last_reload_timestamp_; }
#else
bool IsReloading() const { return false; }
bool HasAttemptedReload() const { return false; }
bool CanReload() const { return false; }
#endif // !defined(DART_PRECOMPILED_RUNTIME)
#endif // !defined(PRODUCT)
bool IsPaused() const;
#if !defined(PRODUCT)
bool should_pause_post_service_request() const {
return ShouldPausePostServiceRequestBit::decode(isolate_flags_);
}
void set_should_pause_post_service_request(bool value) {
isolate_flags_ =
ShouldPausePostServiceRequestBit::update(value, isolate_flags_);
}
#endif // !defined(PRODUCT)
RawError* PausePostRequest();
uword user_tag() const { return user_tag_; }
static intptr_t user_tag_offset() { return OFFSET_OF(Isolate, user_tag_); }
static intptr_t current_tag_offset() {
return OFFSET_OF(Isolate, current_tag_);
}
static intptr_t default_tag_offset() {
return OFFSET_OF(Isolate, default_tag_);
}
#if !defined(PRODUCT)
#define ISOLATE_METRIC_ACCESSOR(type, variable, name, unit) \
type* Get##variable##Metric() { return &metric_##variable##_; }
ISOLATE_METRIC_LIST(ISOLATE_METRIC_ACCESSOR);
#undef ISOLATE_METRIC_ACCESSOR
#endif // !defined(PRODUCT)
static intptr_t IsolateListLength();
RawGrowableObjectArray* tag_table() const { return tag_table_; }
void set_tag_table(const GrowableObjectArray& value);
RawUserTag* current_tag() const { return current_tag_; }
void set_current_tag(const UserTag& tag);
RawUserTag* default_tag() const { return default_tag_; }
void set_default_tag(const UserTag& tag);
void set_ic_miss_code(const Code& code);
#if !defined(PRODUCT)
Metric* metrics_list_head() { return metrics_list_head_; }
void set_metrics_list_head(Metric* metric) { metrics_list_head_ = metric; }
#endif // !defined(PRODUCT)
RawGrowableObjectArray* deoptimized_code_array() const {
return deoptimized_code_array_;
}
void set_deoptimized_code_array(const GrowableObjectArray& value);
void TrackDeoptimizedCode(const Code& code);
// Also sends a paused at exit event over the service protocol.
void SetStickyError(RawError* sticky_error);
RawError* sticky_error() const { return sticky_error_; }
DART_WARN_UNUSED_RESULT RawError* StealStickyError();
void RetainKernelBlob(const ExternalTypedData& kernel_blob);
bool compilation_allowed() const {
return CompilationAllowedBit::decode(isolate_flags_);
}
void set_compilation_allowed(bool allowed) {
isolate_flags_ = CompilationAllowedBit::update(allowed, isolate_flags_);
}
// In precompilation we finalize all regular classes before compiling.
bool all_classes_finalized() const {
return AllClassesFinalizedBit::decode(isolate_flags_);
}
void set_all_classes_finalized(bool value) {
isolate_flags_ = AllClassesFinalizedBit::update(value, isolate_flags_);
}
bool remapping_cids() const {
return RemappingCidsBit::decode(isolate_flags_);
}
void set_remapping_cids(bool value) {
isolate_flags_ = RemappingCidsBit::update(value, isolate_flags_);
}
static const intptr_t kInvalidGen = 0;
void IncrLoadingInvalidationGen() {
AtomicOperations::IncrementBy(&loading_invalidation_gen_, 1);
if (loading_invalidation_gen_ == kInvalidGen) {
AtomicOperations::IncrementBy(&loading_invalidation_gen_, 1);
}
}
intptr_t loading_invalidation_gen() {
return AtomicOperations::LoadRelaxed(&loading_invalidation_gen_);
}
// Used by background compiler which field became boxed and must trigger
// deoptimization in the mutator thread.
void AddDeoptimizingBoxedField(const Field& field);
// Returns Field::null() if none available in the list.
RawField* GetDeoptimizingBoxedField();
#ifndef PRODUCT
RawError* InvokePendingServiceExtensionCalls();
void AppendServiceExtensionCall(const Instance& closure,
const String& method_name,
const Array& parameter_keys,
const Array& parameter_values,
const Instance& reply_port,
const Instance& id);
void RegisterServiceExtensionHandler(const String& name,
const Instance& closure);
RawInstance* LookupServiceExtensionHandler(const String& name);
#endif
static void VisitIsolates(IsolateVisitor* visitor);
#if !defined(PRODUCT)
// Handle service messages until we are told to resume execution.
void PauseEventHandler();
#endif
void AddClosureFunction(const Function& function) const;
RawFunction* LookupClosureFunction(const Function& parent,
TokenPosition token_pos) const;
intptr_t FindClosureIndex(const Function& needle) const;
RawFunction* ClosureFunctionFromIndex(intptr_t idx) const;
bool is_service_isolate() const {
return IsServiceIsolateBit::decode(isolate_flags_);
}
void set_is_service_isolate(bool value) {
isolate_flags_ = IsServiceIsolateBit::update(value, isolate_flags_);
}
bool is_kernel_isolate() const {
return IsKernelIsolateBit::decode(isolate_flags_);
}
void set_is_kernel_isolate(bool value) {
isolate_flags_ = IsKernelIsolateBit::update(value, isolate_flags_);
}
bool can_use_strong_mode_types() const {
return FLAG_use_strong_mode_types && !unsafe_trust_strong_mode_types();
}
// Whether it's possible for unoptimized code to optimize immediately on entry
// (can happen with random or very low optimization counter thresholds)
bool CanOptimizeImmediately() const {
return FLAG_optimization_counter_threshold < 2 ||
FLAG_randomize_optimization_counter;
}
bool should_load_vmservice() const {
return ShouldLoadVmServiceBit::decode(isolate_flags_);
}
void set_should_load_vmservice(bool value) {
isolate_flags_ = ShouldLoadVmServiceBit::update(value, isolate_flags_);
}
Dart_QualifiedFunctionName* embedder_entry_points() const {
return embedder_entry_points_;
}
void set_obfuscation_map(const char** map) { obfuscation_map_ = map; }
const char** obfuscation_map() const { return obfuscation_map_; }
// Returns the pc -> code lookup cache object for this isolate.
ReversePcLookupCache* reverse_pc_lookup_cache() const {
return reverse_pc_lookup_cache_;
}
// Sets the pc -> code lookup cache object for this isolate.
void set_reverse_pc_lookup_cache(ReversePcLookupCache* table) {
ASSERT(reverse_pc_lookup_cache_ == nullptr);
reverse_pc_lookup_cache_ = table;
}
// Isolate-specific flag handling.
static void FlagsInitialize(Dart_IsolateFlags* api_flags);
void FlagsCopyTo(Dart_IsolateFlags* api_flags) const;
void FlagsCopyFrom(const Dart_IsolateFlags& api_flags);
#if defined(DART_PRECOMPILER)
#define FLAG_FOR_PRECOMPILER(from_field, from_flag) (from_field)
#else
#define FLAG_FOR_PRECOMPILER(from_field, from_flag) (from_flag)
#endif
#if !defined(PRODUCT)
#define FLAG_FOR_NONPRODUCT(from_field, from_flag) (from_field)
#else
#define FLAG_FOR_NONPRODUCT(from_field, from_flag) (from_flag)
#endif
#define FLAG_FOR_PRODUCT(from_field, from_flag) (from_field)
#define DECLARE_GETTER(when, name, bitname, isolate_flag_name, flag_name) \
bool name() const { \
const bool false_by_default = false; \
USE(false_by_default); \
return FLAG_FOR_##when(bitname##Bit::decode(isolate_flags_), flag_name); \
}
ISOLATE_FLAG_LIST(DECLARE_GETTER)
#undef FLAG_FOR_NONPRODUCT
#undef FLAG_FOR_PRECOMPILER
#undef FLAG_FOR_PRODUCT
#undef DECLARE_GETTER
#if defined(PRODUCT)
void set_use_osr(bool use_osr) { ASSERT(!use_osr); }
#else // defined(PRODUCT)
void set_use_osr(bool use_osr) {
isolate_flags_ = UseOsrBit::update(use_osr, isolate_flags_);
}
#endif // defined(PRODUCT)
// Convenience flag tester indicating whether incoming function arguments
// should be type checked.
bool argument_type_checks() const { return should_emit_strong_mode_checks(); }
bool should_emit_strong_mode_checks() const {
return !unsafe_trust_strong_mode_types();
}
static void KillAllIsolates(LibMsgId msg_id);
static void KillIfExists(Isolate* isolate, LibMsgId msg_id);
// Lookup an isolate by its main port. Returns NULL if no matching isolate is
// found.
static Isolate* LookupIsolateByPort(Dart_Port port);
static void DisableIsolateCreation();
static void EnableIsolateCreation();
static bool IsolateCreationEnabled();
static bool IsVMInternalIsolate(const Isolate* isolate);
#if !defined(PRODUCT)
intptr_t reload_every_n_stack_overflow_checks() const {
return reload_every_n_stack_overflow_checks_;
}
#endif // !defined(PRODUCT)
HandlerInfoCache* handler_info_cache() { return &handler_info_cache_; }
CatchEntryMovesCache* catch_entry_moves_cache() {
return &catch_entry_moves_cache_;
}
void MaybeIncreaseReloadEveryNStackOverflowChecks();
static void NotifyLowMemory();
private:
friend class Dart; // Init, InitOnce, Shutdown.
friend class IsolateKillerVisitor; // Kill().
explicit Isolate(const Dart_IsolateFlags& api_flags);
static void InitVM();
static Isolate* InitIsolate(const char* name_prefix,
const Dart_IsolateFlags& api_flags,
bool is_vm_isolate = false);
// The isolates_list_monitor_ should be held when calling Kill().
void KillLocked(LibMsgId msg_id);
void LowLevelShutdown();
void Shutdown();
void BuildName(const char* name_prefix);
void ProfileIdle();
// Visit all object pointers. Caller must ensure concurrent sweeper is not
// running, and the visitor must not allocate.
void VisitObjectPointers(ObjectPointerVisitor* visitor,
ValidationPolicy validate_frames);
void VisitStackPointers(ObjectPointerVisitor* visitor,
ValidationPolicy validate_frames);
void set_user_tag(uword tag) { user_tag_ = tag; }
#if !defined(PRODUCT)
RawGrowableObjectArray* GetAndClearPendingServiceExtensionCalls();
RawGrowableObjectArray* pending_service_extension_calls() const {
return pending_service_extension_calls_;
}
void set_pending_service_extension_calls(const GrowableObjectArray& value);
RawGrowableObjectArray* registered_service_extension_handlers() const {
return registered_service_extension_handlers_;
}
void set_registered_service_extension_handlers(
const GrowableObjectArray& value);
#endif // !defined(PRODUCT)
Monitor* threads_lock() const;
Thread* ScheduleThread(bool is_mutator, bool bypass_safepoint = false);
void UnscheduleThread(Thread* thread,
bool is_mutator,
bool bypass_safepoint = false);
// DEPRECATED: Use Thread's methods instead. During migration, these default
// to using the mutator thread (which must also be the current thread).
Zone* current_zone() const {
ASSERT(Thread::Current() == mutator_thread());
return mutator_thread()->zone();
}
// Accessed from generated code.
// ** This block of fields must come first! **
// For AOT cross-compilation, we rely on these members having the same offsets
// in SIMARM(IA32) and ARM, and the same offsets in SIMARM64(X64) and ARM64.
// We use only word-sized fields to avoid differences in struct packing on the
// different architectures. See also CheckOffsets in dart.cc.
uword user_tag_;
RawUserTag* current_tag_;
RawUserTag* default_tag_;
RawCode* ic_miss_code_;
ObjectStore* object_store_;
ClassTable class_table_;
bool single_step_;
// End accessed from generated code.
StoreBuffer* store_buffer_;
MarkingStack* marking_stack_;
MarkingStack* deferred_marking_stack_;
Heap* heap_;
#define ISOLATE_FLAG_BITS(V) \
V(ErrorsFatal) \
V(IsRunnable) \
V(IsServiceIsolate) \
V(IsKernelIsolate) \
V(CompilationAllowed) \
V(AllClassesFinalized) \
V(RemappingCids) \
V(ResumeRequest) \
V(HasAttemptedReload) \
V(ShouldPausePostServiceRequest) \
V(EnableTypeChecks) \
V(EnableAsserts) \
V(ErrorOnBadType) \
V(ErrorOnBadOverride) \
V(UseFieldGuards) \
V(UseOsr) \
V(Obfuscate) \
V(CompactionInProgress) \
V(ShouldLoadVmService) \
V(UnsafeTrustStrongModeTypes)
// Isolate specific flags.
enum FlagBits {
#define DECLARE_BIT(Name) k##Name##Bit,
ISOLATE_FLAG_BITS(DECLARE_BIT)
#undef DECLARE_BIT
};
#define DECLARE_BITFIELD(Name) \
class Name##Bit : public BitField<uint32_t, bool, k##Name##Bit, 1> {};
ISOLATE_FLAG_BITS(DECLARE_BITFIELD)
#undef DECLARE_BITFIELD
uint32_t isolate_flags_;
// Unoptimized background compilation.
BackgroundCompiler* background_compiler_;
// Optimized background compilation.
BackgroundCompiler* optimizing_background_compiler_;
// Fields that aren't needed in a product build go here with boolean flags at
// the top.
#if !defined(PRODUCT)
Debugger* debugger_;
int64_t last_resume_timestamp_;
// Timestamps of last operation via service.
int64_t last_allocationprofile_accumulator_reset_timestamp_;
int64_t last_allocationprofile_gc_timestamp_;
VMTagCounters vm_tag_counters_;
// We use 6 list entries for each pending service extension calls.
enum {
kPendingHandlerIndex = 0,
kPendingMethodNameIndex,
kPendingKeysIndex,
kPendingValuesIndex,
kPendingReplyPortIndex,
kPendingIdIndex,
kPendingEntrySize
};
RawGrowableObjectArray* pending_service_extension_calls_;
// We use 2 list entries for each registered extension handler.
enum {
kRegisteredNameIndex = 0,
kRegisteredHandlerIndex,
kRegisteredEntrySize
};
RawGrowableObjectArray* registered_service_extension_handlers_;
Metric* metrics_list_head_;
// Used to wake the isolate when it is in the pause event loop.
Monitor* pause_loop_monitor_;
#define ISOLATE_METRIC_VARIABLE(type, variable, name, unit) \
type metric_##variable##_;
ISOLATE_METRIC_LIST(ISOLATE_METRIC_VARIABLE);
#undef ISOLATE_METRIC_VARIABLE
intptr_t no_reload_scope_depth_; // we can only reload when this is 0.
// Per-isolate copy of FLAG_reload_every.
intptr_t reload_every_n_stack_overflow_checks_;
IsolateReloadContext* reload_context_;
int64_t last_reload_timestamp_;
// Ring buffer of objects assigned an id.
ObjectIdRing* object_id_ring_;
#endif // !defined(PRODUCT)
// All other fields go here.
int64_t start_time_micros_;
ThreadRegistry* thread_registry_;
SafepointHandler* safepoint_handler_;
Dart_MessageNotifyCallback message_notify_callback_;
char* name_;
Dart_Port main_port_;
Dart_Port origin_id_; // Isolates created by spawnFunc have some origin id.
uint64_t pause_capability_;
uint64_t terminate_capability_;
void* init_callback_data_;
Dart_EnvironmentCallback environment_callback_;
Dart_LibraryTagHandler library_tag_handler_;
ApiState* api_state_;
Random random_;
Simulator* simulator_;
Mutex* mutex_; // Protects compiler stats.
Mutex* symbols_mutex_; // Protects concurrent access to the symbol table.
Mutex* type_canonicalization_mutex_; // Protects type canonicalization.
Mutex* constant_canonicalization_mutex_; // Protects const canonicalization.