Files
sdk/runtime/vm/message.h
T
Slava Egorov 53ac68e2dd [vm_service] Deprecate Stack.messages
Make VM always return empty array in the response.

Current implementation for this field comes with a bunch of complexity
because it locks message handler and then invokes Dart code which
makes it difficult to reason about various invariants. This code is 
furthermore demonstrated to cause deadlocks. Given that nobody uses 
it - it is simpler to remove this code altogether.

Fixes https://github.com/flutter/flutter/issues/185156

TEST=ci

Change-Id: I497210e0f1542860caa0d765d634f8ec6a6a6964
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/496340
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Slava Egorov <vegorov@google.com>
2026-04-20 10:28:01 -07:00

200 lines
5.7 KiB
C++

// 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 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();
}
}
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;
private:
Message* head_;
Message* tail_;
DISALLOW_COPY_AND_ASSIGN(MessageQueue);
};
} // namespace dart
#endif // RUNTIME_VM_MESSAGE_H_