Flutter Engine
The Flutter Engine
message.cc
Go to the documentation of this file.
1// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
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.
4
5#include "vm/message.h"
6
7#include <utility>
8
9#include "vm/dart_api_state.h"
10#include "vm/dart_entry.h"
11#include "vm/json_stream.h"
12#include "vm/object.h"
13#include "vm/port.h"
14
15namespace dart {
16
18
20 uint8_t* snapshot,
21 intptr_t snapshot_length,
22 MessageFinalizableData* finalizable_data,
23 Priority priority)
24 : dest_port_(dest_port),
25 payload_(snapshot),
26 snapshot_length_(snapshot_length),
27 finalizable_data_(finalizable_data),
28 priority_(priority) {
30}
31
32Message::Message(Dart_Port dest_port, ObjectPtr raw_obj, Priority priority)
33 : dest_port_(dest_port), payload_(raw_obj), priority_(priority) {
34 ASSERT(!raw_obj->IsHeapObject() || raw_obj->untag()->InVMIsolateHeap());
35 ASSERT(IsRaw());
36}
37
39 PersistentHandle* handle,
40 Priority priority)
41 : dest_port_(dest_port),
42 payload_(handle),
43 snapshot_length_(kPersistentHandleSnapshotLen),
44 priority_(priority) {
46}
47
49 : dest_port_(ILLEGAL_PORT),
50 payload_(handle),
51 snapshot_length_(kFinalizerSnapshotLen),
52 priority_(priority) {
54}
55
57 if (IsSnapshot()) {
58 free(payload_.snapshot_);
59 }
60 delete finalizable_data_;
62 auto isolate_group = IsolateGroup::Current();
63 isolate_group->api_state()->FreePersistentHandle(
64 payload_.persistent_handle_);
65 }
66}
67
68intptr_t Message::Id() const {
69 // Messages are allocated on the C heap. Use the raw address as the id.
70 return reinterpret_cast<intptr_t>(this);
71}
72
73const char* Message::PriorityAsString(Priority priority) {
74 switch (priority) {
75 case kNormalPriority:
76 return "Normal";
77 break;
78 case kOOBPriority:
79 return "OOB";
80 break;
81 default:
83 return nullptr;
84 }
85}
86
88 head_ = nullptr;
89 tail_ = nullptr;
90}
91
93 // Ensure that all pending messages have been released.
94 Clear();
95 ASSERT(head_ == nullptr);
96}
97
98void MessageQueue::Enqueue(std::unique_ptr<Message> msg0, bool before_events) {
99 // TODO(mdempsky): Use unique_ptr internally?
100 Message* msg = msg0.release();
101
102 // Make sure messages are not reused.
103 ASSERT(msg->next_ == nullptr);
104 if (head_ == nullptr) {
105 // Only element in the queue.
106 ASSERT(tail_ == nullptr);
107 head_ = msg;
108 tail_ = msg;
109 } else {
110 ASSERT(tail_ != nullptr);
111 if (!before_events) {
112 // Append at the tail.
113 tail_->next_ = msg;
114 tail_ = msg;
115 } else {
117 if (head_->dest_port() != Message::kIllegalPort) {
118 msg->next_ = head_;
119 head_ = msg;
120 } else {
121 Message* cur = head_;
122 while (cur->next_ != nullptr) {
123 if (cur->next_->dest_port() != Message::kIllegalPort) {
124 // Splice in the new message at the break.
125 msg->next_ = cur->next_;
126 cur->next_ = msg;
127 return;
128 }
129 cur = cur->next_;
130 }
131 // All pending messages are isolate library control messages. Append at
132 // the tail.
133 ASSERT(tail_ == cur);
135 tail_->next_ = msg;
136 tail_ = msg;
137 }
138 }
139 }
140}
141
142std::unique_ptr<Message> MessageQueue::Dequeue() {
143 Message* result = head_;
144 if (result != nullptr) {
145 head_ = result->next_;
146 // The following update to tail_ is not strictly needed.
147 if (head_ == nullptr) {
148 tail_ = nullptr;
149 }
150#if defined(DEBUG)
151 result->next_ = result; // Make sure to trigger ASSERT in Enqueue.
152#endif // DEBUG
153 return std::unique_ptr<Message>(result);
154 }
155 return nullptr;
156}
157
159 std::unique_ptr<Message> cur(head_);
160 head_ = nullptr;
161 tail_ = nullptr;
162 while (cur != nullptr) {
163 std::unique_ptr<Message> next(cur->next_);
164 cur = std::move(next);
165 }
166}
167
169 Reset(queue);
170}
171
173
175 ASSERT(queue != nullptr);
176 next_ = queue->head_;
177}
178
179// returns false when there are no more messages left.
181 return next_ != nullptr;
182}
183
184// Returns the current message and moves forward.
186 Message* current = next_;
187 next_ = next_->next_;
188 return current;
189}
190
191intptr_t MessageQueue::Length() const {
192 MessageQueue::Iterator it(this);
193 intptr_t length = 0;
194 while (it.HasNext()) {
195 it.Next();
196 length++;
197 }
198 return length;
199}
200
202 MessageQueue::Iterator it(this);
203 while (it.HasNext()) {
204 Message* current = it.Next();
205 ASSERT(current != nullptr);
206 if (current->Id() == id) {
207 return current;
208 }
209 }
210 return nullptr;
211}
212
214#ifndef PRODUCT
215 JSONArray messages(stream);
216
217 Object& msg_handler = Object::Handle();
218
219 MessageQueue::Iterator it(this);
220 intptr_t depth = 0;
221 while (it.HasNext()) {
222 Message* current = it.Next();
223 JSONObject message(&messages);
224 message.AddProperty("type", "Message");
225 message.AddPropertyF("name", "Isolate Message (%" Px ")", current->Id());
226 message.AddPropertyF("messageObjectId", "messages/%" Px "", current->Id());
227 message.AddProperty("size", current->Size());
228 message.AddProperty("index", depth++);
229 message.AddPropertyF("_destinationPort", "%" Pd64 "",
230 static_cast<int64_t>(current->dest_port()));
231 message.AddProperty("_priority",
233 // TODO(johnmccutchan): Move port -> handler map out of Dart and into the
234 // VM, that way we can lookup the handler without invoking Dart code.
235 msg_handler = DartLibraryCalls::LookupHandler(current->dest_port());
236 if (msg_handler.IsClosure()) {
237 // Grab function from closure.
238 msg_handler = Closure::Cast(msg_handler).function();
239 }
240 if (msg_handler.IsFunction()) {
241 const Function& function = Function::Cast(msg_handler);
242 message.AddProperty("handler", function);
243
244 const Script& script = Script::Handle(function.script());
245 if (!script.IsNull()) {
246 message.AddLocation(script, function.token_pos(),
247 function.end_token_pos());
248 }
249 }
250 }
251#endif // !PRODUCT
252}
253
254} // namespace dart
static float next(float f)
static ObjectPtr LookupHandler(Dart_Port port_id)
Definition: dart_entry.cc:664
static IsolateGroup * Current()
Definition: isolate.h:539
Iterator(const MessageQueue *queue)
Definition: message.cc:168
void Reset(const MessageQueue *queue)
Definition: message.cc:174
Message * FindMessageById(intptr_t id)
Definition: message.cc:201
intptr_t Length() const
Definition: message.cc:191
void Enqueue(std::unique_ptr< Message > msg, bool before_events)
Definition: message.cc:98
void PrintJSON(JSONStream *stream)
Definition: message.cc:213
std::unique_ptr< Message > Dequeue()
Definition: message.cc:142
bool IsSnapshot() const
Definition: message.h:108
bool IsPersistentHandle() const
Definition: message.h:115
Priority priority() const
Definition: message.h:102
intptr_t Id() const
Definition: message.cc:68
ObjectPtr raw_obj() const
Definition: message.h:94
intptr_t Size() const
Definition: message.h:86
Dart_Port dest_port() const
Definition: message.h:76
static const Dart_Port kIllegalPort
Definition: message.h:47
bool IsRaw() const
Definition: message.h:112
@ kNormalPriority
Definition: message.h:28
@ kOOBPriority
Definition: message.h:29
Message(Dart_Port dest_port, uint8_t *snapshot, intptr_t snapshot_length, MessageFinalizableData *finalizable_data, Priority priority)
Definition: message.cc:19
static const char * PriorityAsString(Priority priority)
Definition: message.cc:73
bool IsFinalizerInvocationRequest() const
Definition: message.h:119
UntaggedObject * untag() const
static Object & Handle()
Definition: object.h:407
bool InVMIsolateHeap() const
Definition: raw_object.cc:20
#define ILLEGAL_PORT
Definition: dart_api.h:1535
int64_t Dart_Port
Definition: dart_api.h:1525
#define UNIMPLEMENTED
#define ASSERT(E)
VkQueue queue
Definition: main.cc:55
GAsyncResult * result
Dart_NativeFunction function
Definition: fuchsia.cc:51
size_t length
Win32Message message
Definition: dart_vm.cc:33
#define Px
Definition: globals.h:410
#define Pd64
Definition: globals.h:416