mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 06:20:13 +00:00
386338edd8
This improves performance of SendPort.Receive.Nop benchmark with isolate groups enabled on Intel Xeon by ~17%. This benchmark emphasizes performance of handle message flow. Issue https://github.com/dart-lang/sdk/issues/46752 TEST=ci Change-Id: I3b9be3283047631e8989bb56f90af2b3b007afe8 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/209642 Commit-Queue: Alexander Aprelev <aam@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com>
323 lines
13 KiB
C++
323 lines
13 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_DART_ENTRY_H_
|
|
#define RUNTIME_VM_DART_ENTRY_H_
|
|
|
|
#include "vm/allocation.h"
|
|
#include "vm/growable_array.h"
|
|
#include "vm/object.h"
|
|
#include "vm/raw_object.h"
|
|
|
|
namespace dart {
|
|
|
|
// Forward declarations.
|
|
class Array;
|
|
class Closure;
|
|
class Function;
|
|
class Instance;
|
|
class Integer;
|
|
class Library;
|
|
class Object;
|
|
class String;
|
|
|
|
// An arguments descriptor array consists of the type argument vector length (0
|
|
// if none); total argument count (not counting type argument vector); total
|
|
// arguments size (not counting type argument vector); the positional argument
|
|
// count; a sequence of (name, position) pairs, sorted by name, for each named
|
|
// optional argument; and a terminating null to simplify iterating in generated
|
|
// code.
|
|
class ArgumentsDescriptor : public ValueObject {
|
|
public:
|
|
explicit ArgumentsDescriptor(const Array& array);
|
|
|
|
// Accessors.
|
|
intptr_t TypeArgsLen() const; // 0 if no type argument vector is passed.
|
|
intptr_t FirstArgIndex() const { return TypeArgsLen() > 0 ? 1 : 0; }
|
|
intptr_t CountWithTypeArgs() const { return FirstArgIndex() + Count(); }
|
|
intptr_t Count() const; // Excluding type arguments vector.
|
|
intptr_t Size() const; // Excluding type arguments vector.
|
|
intptr_t SizeWithTypeArgs() const { return FirstArgIndex() + Size(); }
|
|
intptr_t PositionalCount() const; // Excluding type arguments vector.
|
|
intptr_t NamedCount() const { return Count() - PositionalCount(); }
|
|
StringPtr NameAt(intptr_t i) const;
|
|
intptr_t PositionAt(intptr_t i) const;
|
|
bool MatchesNameAt(intptr_t i, const String& other) const;
|
|
// Returns array of argument names in the arguments order.
|
|
ArrayPtr GetArgumentNames() const;
|
|
void PrintTo(BaseTextBuffer* buffer, bool show_named_positions = false) const;
|
|
const char* ToCString() const;
|
|
|
|
// Generated code support.
|
|
static intptr_t type_args_len_offset() {
|
|
return Array::element_offset(kTypeArgsLenIndex);
|
|
}
|
|
|
|
static intptr_t count_offset() { return Array::element_offset(kCountIndex); }
|
|
|
|
static intptr_t size_offset() { return Array::element_offset(kSizeIndex); }
|
|
|
|
static intptr_t positional_count_offset() {
|
|
return Array::element_offset(kPositionalCountIndex);
|
|
}
|
|
|
|
static intptr_t first_named_entry_offset() {
|
|
return Array::element_offset(kFirstNamedEntryIndex);
|
|
}
|
|
|
|
static intptr_t name_offset() { return kNameOffset * kCompressedWordSize; }
|
|
static intptr_t position_offset() {
|
|
return kPositionOffset * kCompressedWordSize;
|
|
}
|
|
static intptr_t named_entry_size() {
|
|
return kNamedEntrySize * kCompressedWordSize;
|
|
}
|
|
|
|
// Constructs an argument descriptor where all arguments are boxed and
|
|
// therefore number of parameters equals parameter size.
|
|
//
|
|
// Right now this is for example the case for all closure functions.
|
|
// Functions marked as entry-points may also be created by NewUnboxed because
|
|
// we rely that TFA will mark the arguments as nullable for such cases.
|
|
static ArrayPtr NewBoxed(intptr_t type_args_len,
|
|
intptr_t num_arguments,
|
|
const Array& optional_arguments_names,
|
|
Heap::Space space = Heap::kOld) {
|
|
return New(type_args_len, num_arguments, num_arguments,
|
|
optional_arguments_names, space);
|
|
}
|
|
|
|
// Allocate and return an arguments descriptor. The first
|
|
// (num_arguments - optional_arguments_names.Length()) arguments are
|
|
// positional and the remaining ones are named optional arguments.
|
|
// The presence of a type argument vector as first argument (not counted in
|
|
// num_arguments) is indicated by a non-zero type_args_len.
|
|
static ArrayPtr New(intptr_t type_args_len,
|
|
intptr_t num_arguments,
|
|
intptr_t size_arguments,
|
|
const Array& optional_arguments_names,
|
|
Heap::Space space = Heap::kOld);
|
|
|
|
// Constructs an argument descriptor where all arguments are boxed and
|
|
// therefore number of parameters equals parameter size.
|
|
//
|
|
// Right now this is for example the case for all closure functions.
|
|
static ArrayPtr NewBoxed(intptr_t type_args_len,
|
|
intptr_t num_arguments,
|
|
Heap::Space space = Heap::kOld) {
|
|
return New(type_args_len, num_arguments, num_arguments, space);
|
|
}
|
|
|
|
// Allocate and return an arguments descriptor that has no optional
|
|
// arguments. All arguments are positional. The presence of a type argument
|
|
// vector as first argument (not counted in num_arguments) is indicated
|
|
// by a non-zero type_args_len.
|
|
static ArrayPtr New(intptr_t type_args_len,
|
|
intptr_t num_arguments,
|
|
intptr_t size_arguments,
|
|
Heap::Space space = Heap::kOld);
|
|
|
|
// Initialize the preallocated fixed length arguments descriptors cache.
|
|
static void Init();
|
|
|
|
// Clear the preallocated fixed length arguments descriptors cache.
|
|
static void Cleanup();
|
|
|
|
enum { kCachedDescriptorCount = 32 };
|
|
|
|
// For creating ArgumentDescriptor Slots.
|
|
static constexpr bool ContainsCompressedPointers() {
|
|
// Use the same state as the backing store.
|
|
return Array::ContainsCompressedPointers();
|
|
}
|
|
|
|
private:
|
|
// Absolute indices into the array.
|
|
// Keep these in sync with the constants in invocation_mirror_patch.dart.
|
|
enum {
|
|
kTypeArgsLenIndex,
|
|
kCountIndex,
|
|
kSizeIndex,
|
|
kPositionalCountIndex,
|
|
kFirstNamedEntryIndex,
|
|
};
|
|
|
|
private:
|
|
// Relative indexes into each named argument entry.
|
|
enum {
|
|
kNameOffset,
|
|
// The least significant bit of the entry in 'kPositionOffset' (second
|
|
// least-significant after Smi-encoding) holds the strong-mode checking bit
|
|
// for the named argument.
|
|
kPositionOffset,
|
|
kNamedEntrySize,
|
|
};
|
|
|
|
public:
|
|
static intptr_t LengthFor(intptr_t num_named_arguments) {
|
|
// Add 1 for the terminating null.
|
|
return kFirstNamedEntryIndex + (kNamedEntrySize * num_named_arguments) + 1;
|
|
}
|
|
|
|
static ArrayPtr NewNonCached(intptr_t type_args_len,
|
|
intptr_t num_arguments,
|
|
intptr_t size_arguments,
|
|
bool canonicalize,
|
|
Heap::Space space);
|
|
|
|
// Used by Simulator to parse argument descriptors.
|
|
static intptr_t name_index(intptr_t index) {
|
|
return kFirstNamedEntryIndex + (index * kNamedEntrySize) + kNameOffset;
|
|
}
|
|
|
|
static intptr_t position_index(intptr_t index) {
|
|
return kFirstNamedEntryIndex + (index * kNamedEntrySize) + kPositionOffset;
|
|
}
|
|
|
|
const Array& array_;
|
|
|
|
// A cache of VM heap allocated arguments descriptors.
|
|
static ArrayPtr cached_args_descriptors_[kCachedDescriptorCount];
|
|
|
|
friend class Serializer;
|
|
friend class Deserializer;
|
|
friend class Simulator;
|
|
friend class SimulatorHelpers;
|
|
DISALLOW_COPY_AND_ASSIGN(ArgumentsDescriptor);
|
|
};
|
|
|
|
// DartEntry abstracts functionality needed to resolve dart functions
|
|
// and invoke them from C++.
|
|
class DartEntry : public AllStatic {
|
|
public:
|
|
// Invokes the specified instance function or static function.
|
|
// The first argument of an instance function is the receiver.
|
|
// On success, returns an InstancePtr. On failure, an ErrorPtr.
|
|
// This is used when there is no type argument vector and
|
|
// no named arguments in the call.
|
|
static ObjectPtr InvokeFunction(const Function& function,
|
|
const Array& arguments);
|
|
|
|
// Invokes the specified code as if it was a Dart function.
|
|
// On success, returns an InstancePtr. On failure, an ErrorPtr.
|
|
static ObjectPtr InvokeCode(const Code& code,
|
|
uword entry_point,
|
|
const Array& arguments_descriptor,
|
|
const Array& arguments,
|
|
Thread* thread);
|
|
|
|
// Invokes the specified instance, static, or closure function.
|
|
// On success, returns an InstancePtr. On failure, an ErrorPtr.
|
|
static ObjectPtr InvokeFunction(
|
|
const Function& function,
|
|
const Array& arguments,
|
|
const Array& arguments_descriptor,
|
|
uword current_sp = OSThread::GetCurrentStackPointer());
|
|
|
|
// Invokes the first argument in the provided arguments array as a callable
|
|
// object, performing any needed dynamic checks if the callable cannot receive
|
|
// dynamic invocation.
|
|
//
|
|
// On success, returns an InstancePtr. On failure, an ErrorPtr.
|
|
//
|
|
// Used when an ArgumentsDescriptor is not required, that is, when there
|
|
// are no type arguments or named arguments.
|
|
static ObjectPtr InvokeClosure(Thread* thread, const Array& arguments);
|
|
|
|
// Invokes the first argument in the provided arguments array as a callable
|
|
// object, performing any needed dynamic checks if the callable cannot receive
|
|
// dynamic invocation.
|
|
//
|
|
// On success, returns an InstancePtr. On failure, an ErrorPtr.
|
|
static ObjectPtr InvokeClosure(Thread* thread,
|
|
const Array& arguments,
|
|
const Array& arguments_descriptor);
|
|
|
|
// Invokes the noSuchMethod instance function on the receiver.
|
|
// On success, returns an InstancePtr. On failure, an ErrorPtr.
|
|
static ObjectPtr InvokeNoSuchMethod(Thread* thread,
|
|
const Instance& receiver,
|
|
const String& target_name,
|
|
const Array& arguments,
|
|
const Array& arguments_descriptor);
|
|
|
|
private:
|
|
// Resolves the first argument in the provided arguments array to a callable
|
|
// compatible with the arguments. Helper method used within InvokeClosure.
|
|
//
|
|
// If no errors occur, the first argument is changed to be either the resolved
|
|
// callable or, if Function::null() is returned, an appropriate target for
|
|
// invoking noSuchMethod.
|
|
//
|
|
// On success, returns a FunctionPtr. On failure, an ErrorPtr.
|
|
static ObjectPtr ResolveCallable(Thread* thread,
|
|
const Array& arguments,
|
|
const Array& arguments_descriptor);
|
|
|
|
// Invokes a function returned by ResolveCallable, performing any dynamic
|
|
// checks needed if the function cannot receive dynamic invocation. Helper
|
|
// method used within InvokeClosure.
|
|
//
|
|
// On success, returns an InstancePtr. On failure, an ErrorPtr.
|
|
static ObjectPtr InvokeCallable(Thread* thread,
|
|
const Function& callable_function,
|
|
const Array& arguments,
|
|
const Array& arguments_descriptor);
|
|
};
|
|
|
|
// Utility functions to call from VM into Dart bootstrap libraries.
|
|
// Each may return an exception object.
|
|
class DartLibraryCalls : public AllStatic {
|
|
public:
|
|
// On success, returns an InstancePtr. On failure, an ErrorPtr.
|
|
static ObjectPtr InstanceCreate(const Library& library,
|
|
const String& exception_name,
|
|
const String& constructor_name,
|
|
const Array& arguments);
|
|
|
|
// On success, returns an InstancePtr. On failure, an ErrorPtr.
|
|
static ObjectPtr ToString(const Instance& receiver);
|
|
|
|
// On success, returns an InstancePtr. On failure, an ErrorPtr.
|
|
static ObjectPtr HashCode(const Instance& receiver);
|
|
|
|
// On success, returns an InstancePtr. On failure, an ErrorPtr.
|
|
static ObjectPtr Equals(const Instance& left, const Instance& right);
|
|
|
|
// On success, returns an InstancePtr. On failure, an ErrorPtr.
|
|
static ObjectPtr IdentityHashCode(const Instance& object);
|
|
|
|
// Returns the handler if one has been registered for this port id.
|
|
static ObjectPtr LookupHandler(Dart_Port port_id);
|
|
|
|
// Returns handler on success, an ErrorPtr on failure, null if can't find
|
|
// handler for this port id.
|
|
static ObjectPtr HandleMessage(Dart_Port port_id, const Instance& message);
|
|
|
|
// Returns a list of open ReceivePorts.
|
|
static ObjectPtr LookupOpenPorts();
|
|
|
|
|
|
// Returns null on success, an ErrorPtr on failure.
|
|
static ObjectPtr DrainMicrotaskQueue();
|
|
|
|
// Ensures that the isolate's _pendingImmediateCallback is set to
|
|
// _startMicrotaskLoop from dart:async.
|
|
// Returns null on success, an ErrorPtr on failure.
|
|
static ObjectPtr EnsureScheduleImmediate();
|
|
|
|
// Runs the `_rehashObjects()` function in `dart:collection`.
|
|
static ObjectPtr RehashObjectsInDartCollection(
|
|
Thread* thread,
|
|
const Object& array_or_growable_array);
|
|
|
|
// Runs the `_rehashObjects()` function in `dart:core`.
|
|
static ObjectPtr RehashObjectsInDartCore(
|
|
Thread* thread,
|
|
const Object& array_or_growable_array);
|
|
};
|
|
|
|
} // namespace dart
|
|
|
|
#endif // RUNTIME_VM_DART_ENTRY_H_
|