-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
Copy pathmessage.h
209 lines (162 loc) · 5.88 KB
/
message.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
// Copyright (c) 2011, 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_MESSAGE_H_
#define RUNTIME_VM_MESSAGE_H_
#include <memory>
#include <utility>
#include "platform/assert.h"
#include "vm/allocation.h"
#include "vm/finalizable_data.h"
#include "vm/globals.h"
#include "vm/tagged_pointer.h"
// Duplicated from dart_api.h to avoid including the whole header.
typedef int64_t Dart_Port;
namespace dart {
class JSONStream;
class PersistentHandle;
class Message {
public:
typedef enum {
kNormalPriority = 0, // Deliver message when idle.
kOOBPriority = 1, // Deliver message asap.
// Iteration.
kFirstPriority = 0,
kNumPriorities = 2,
} Priority;
// Values defining the type of OOB messages. OOB messages can only be
// fixed length arrays where the first element is a Smi with one of the
// valid values below.
typedef enum {
kIllegalOOB = 0,
kServiceOOBMsg = 1,
kIsolateLibOOBMsg = 2,
kDelayedIsolateLibOOBMsg = 3,
} OOBMsgTag;
// A port number which is never used.
static const Dart_Port kIllegalPort;
// A new message to be sent between two isolates. The data handed to this
// message will be disposed by calling free() once the message object is
// being destructed (after delivery or when the receiving port is closed).
Message(Dart_Port dest_port,
uint8_t* snapshot,
intptr_t snapshot_length,
MessageFinalizableData* finalizable_data,
Priority priority);
// Message objects can also carry raw ObjectPtr for Smis and objects in
// the VM heap. This is indicated by setting the len_ field to 0.
Message(Dart_Port dest_port, ObjectPtr raw_obj, Priority priority);
// A message sent from SendPort.send or SendPort.sendAndExit where sender and
// receiver are in the same isolate group.
Message(Dart_Port dest_port, PersistentHandle* handle, Priority priority);
// A message sent from GC to run a finalizer.
Message(PersistentHandle* handle, Priority priority);
~Message();
template <typename... Args>
static std::unique_ptr<Message> New(Args&&... args) {
return std::unique_ptr<Message>(new Message(std::forward<Args>(args)...));
}
Dart_Port dest_port() const { return dest_port_; }
uint8_t* snapshot() const {
ASSERT(IsSnapshot());
return payload_.snapshot_;
}
intptr_t snapshot_length() const { return snapshot_length_; }
MessageFinalizableData* finalizable_data() { return finalizable_data_; }
intptr_t Size() const {
intptr_t size = snapshot_length_;
if (finalizable_data_ != nullptr) {
size += finalizable_data_->external_size();
}
return size;
}
ObjectPtr raw_obj() const {
ASSERT(IsRaw());
return payload_.raw_obj_;
}
PersistentHandle* persistent_handle() const {
ASSERT(IsPersistentHandle() || IsFinalizerInvocationRequest());
return payload_.persistent_handle_;
}
Priority priority() const { return priority_; }
// A message processed at any interrupt point (stack overflow check) instead
// of at the top of the message loop. Control messages from dart:isolate or
// vm-service requests.
bool IsOOB() const { return priority_ == Message::kOOBPriority; }
bool IsSnapshot() const {
return !IsRaw() && !IsPersistentHandle() && !IsFinalizerInvocationRequest();
}
// A message whose object is an immortal object from the vm-isolate's heap.
bool IsRaw() const { return snapshot_length_ == 0; }
// A message sent from SendPort.send or SendPort.sendAndExit where sender and
// receiver are in the same isolate group.
bool IsPersistentHandle() const {
return snapshot_length_ == kPersistentHandleSnapshotLen;
}
// A message sent from GC to run a finalizer.
bool IsFinalizerInvocationRequest() const {
return snapshot_length_ == kFinalizerSnapshotLen;
}
void DropFinalizers() {
if (finalizable_data_ != nullptr) {
finalizable_data_->DropFinalizers();
}
}
intptr_t Id() const;
static const char* PriorityAsString(Priority priority);
private:
static intptr_t const kPersistentHandleSnapshotLen = -1;
static intptr_t const kFinalizerSnapshotLen = -2;
friend class MessageQueue;
Message* next_ = nullptr;
Dart_Port dest_port_;
union Payload {
Payload(uint8_t* snapshot) : snapshot_(snapshot) {}
Payload(ObjectPtr raw_obj) : raw_obj_(raw_obj) {}
Payload(PersistentHandle* persistent_handle)
: persistent_handle_(persistent_handle) {}
uint8_t* snapshot_;
ObjectPtr raw_obj_;
PersistentHandle* persistent_handle_;
} payload_;
intptr_t snapshot_length_ = 0;
MessageFinalizableData* finalizable_data_ = nullptr;
Priority priority_;
DISALLOW_COPY_AND_ASSIGN(Message);
};
// There is a message queue per isolate.
class MessageQueue {
public:
MessageQueue();
~MessageQueue();
void Enqueue(std::unique_ptr<Message> msg, bool before_events);
// Gets the next message from the message queue or nullptr if no
// message is available. This function will not block.
std::unique_ptr<Message> Dequeue();
bool IsEmpty() { return head_ == nullptr; }
// Clear all messages from the message queue.
void Clear();
// Iterator class.
class Iterator : public ValueObject {
public:
explicit Iterator(const MessageQueue* queue);
virtual ~Iterator();
void Reset(const MessageQueue* queue);
// Returns false when there are no more messages left.
bool HasNext();
// Returns the current message and moves forward.
Message* Next();
private:
Message* next_;
};
intptr_t Length() const;
// Returns the message with id or nullptr.
Message* FindMessageById(intptr_t id);
void PrintJSON(JSONStream* stream);
private:
Message* head_;
Message* tail_;
DISALLOW_COPY_AND_ASSIGN(MessageQueue);
};
} // namespace dart
#endif // RUNTIME_VM_MESSAGE_H_