dart-sdk/runtime/vm/deferred_objects.h
Alexander Markov dea3fa7b8c [vm/compiler] Allocation sinking of arrays and typed data objects
JIT mode: ParticleSystemUpdate +44-52%
JIT mode with null safety: ParticleSystemUpdate +40-44%

In AOT mode a few methods from package:vector_math are not inlined
in ParticleSystemUpdate benchmarks, which prevents allocation
sinking optimization.

Closes https://github.com/dart-lang/sdk/issues/43228

Change-Id: I28d5816e643e4cfffe4b4fb7db5db5a3aa72499c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/164805
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2020-10-16 20:05:02 +00:00

255 lines
6.7 KiB
C++

// 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_DEFERRED_OBJECTS_H_
#define RUNTIME_VM_DEFERRED_OBJECTS_H_
#include "platform/globals.h"
#include "vm/tagged_pointer.h"
namespace dart {
// Forward declarations.
class Object;
class DeoptContext;
// Used by the deoptimization infrastructure to defer allocation of
// unboxed objects until frame is fully rewritten and GC is safe.
// Describes a stack slot that should be populated with a reference to
// the materialized object.
class DeferredSlot {
public:
DeferredSlot(ObjectPtr* slot, DeferredSlot* next)
: slot_(slot), next_(next) {}
virtual ~DeferredSlot() {}
ObjectPtr* slot() const { return slot_; }
DeferredSlot* next() const { return next_; }
virtual void Materialize(DeoptContext* deopt_context) = 0;
private:
ObjectPtr* const slot_;
DeferredSlot* const next_;
DISALLOW_COPY_AND_ASSIGN(DeferredSlot);
};
class DeferredDouble : public DeferredSlot {
public:
DeferredDouble(double value, ObjectPtr* slot, DeferredSlot* next)
: DeferredSlot(slot, next), value_(value) {}
virtual void Materialize(DeoptContext* deopt_context);
double value() const { return value_; }
private:
const double value_;
DISALLOW_COPY_AND_ASSIGN(DeferredDouble);
};
class DeferredMint : public DeferredSlot {
public:
DeferredMint(int64_t value, ObjectPtr* slot, DeferredSlot* next)
: DeferredSlot(slot, next), value_(value) {}
virtual void Materialize(DeoptContext* deopt_context);
int64_t value() const { return value_; }
private:
const int64_t value_;
DISALLOW_COPY_AND_ASSIGN(DeferredMint);
};
class DeferredFloat32x4 : public DeferredSlot {
public:
DeferredFloat32x4(simd128_value_t value, ObjectPtr* slot, DeferredSlot* next)
: DeferredSlot(slot, next), value_(value) {}
virtual void Materialize(DeoptContext* deopt_context);
simd128_value_t value() const { return value_; }
private:
const simd128_value_t value_;
DISALLOW_COPY_AND_ASSIGN(DeferredFloat32x4);
};
class DeferredFloat64x2 : public DeferredSlot {
public:
DeferredFloat64x2(simd128_value_t value, ObjectPtr* slot, DeferredSlot* next)
: DeferredSlot(slot, next), value_(value) {}
virtual void Materialize(DeoptContext* deopt_context);
simd128_value_t value() const { return value_; }
private:
const simd128_value_t value_;
DISALLOW_COPY_AND_ASSIGN(DeferredFloat64x2);
};
class DeferredInt32x4 : public DeferredSlot {
public:
DeferredInt32x4(simd128_value_t value, ObjectPtr* slot, DeferredSlot* next)
: DeferredSlot(slot, next), value_(value) {}
virtual void Materialize(DeoptContext* deopt_context);
simd128_value_t value() const { return value_; }
private:
const simd128_value_t value_;
DISALLOW_COPY_AND_ASSIGN(DeferredInt32x4);
};
// Describes a slot that contains a reference to an object that had its
// allocation removed by AllocationSinking pass.
// Object itself is described and materialized by DeferredObject.
class DeferredObjectRef : public DeferredSlot {
public:
DeferredObjectRef(intptr_t index, ObjectPtr* slot, DeferredSlot* next)
: DeferredSlot(slot, next), index_(index) {}
virtual void Materialize(DeoptContext* deopt_context);
intptr_t index() const { return index_; }
private:
const intptr_t index_;
DISALLOW_COPY_AND_ASSIGN(DeferredObjectRef);
};
class DeferredRetAddr : public DeferredSlot {
public:
DeferredRetAddr(intptr_t index,
intptr_t deopt_id,
ObjectPtr* slot,
DeferredSlot* next)
: DeferredSlot(slot, next), index_(index), deopt_id_(deopt_id) {}
virtual void Materialize(DeoptContext* deopt_context);
intptr_t index() const { return index_; }
private:
const intptr_t index_;
const intptr_t deopt_id_;
DISALLOW_COPY_AND_ASSIGN(DeferredRetAddr);
};
class DeferredPcMarker : public DeferredSlot {
public:
DeferredPcMarker(intptr_t index, ObjectPtr* slot, DeferredSlot* next)
: DeferredSlot(slot, next), index_(index) {}
virtual void Materialize(DeoptContext* deopt_context);
intptr_t index() const { return index_; }
private:
const intptr_t index_;
DISALLOW_COPY_AND_ASSIGN(DeferredPcMarker);
};
class DeferredPp : public DeferredSlot {
public:
DeferredPp(intptr_t index, ObjectPtr* slot, DeferredSlot* next)
: DeferredSlot(slot, next), index_(index) {}
virtual void Materialize(DeoptContext* deopt_context);
intptr_t index() const { return index_; }
private:
const intptr_t index_;
DISALLOW_COPY_AND_ASSIGN(DeferredPp);
};
// Describes an object which allocation was removed by AllocationSinking pass.
// Arguments for materialization are stored as a part of expression stack
// for the bottommost deoptimized frame so that GC could discover them.
// They will be removed from the stack at the very end of deoptimization.
class DeferredObject {
public:
DeferredObject(intptr_t field_count, intptr_t* args)
: field_count_(field_count),
args_(reinterpret_cast<ObjectPtr*>(args)),
object_(NULL) {}
intptr_t ArgumentCount() const {
return kFieldsStartIndex + kFieldEntrySize * field_count_;
}
ObjectPtr object();
// Fill object with actual field values.
void Fill();
private:
enum {
kClassIndex = 0,
// Number of context variables for contexts,
// number of elements for arrays and typed data objects,
// -1 otherwise.
kLengthIndex,
kFieldsStartIndex
};
enum {
kOffsetIndex = 0,
kValueIndex,
kFieldEntrySize,
};
// Allocate the object but keep its fields null-initialized. Actual field
// values will be filled later by the Fill method. This separation between
// allocation and filling is needed because dematerialized objects form
// a graph which can contain cycles.
void Create();
ObjectPtr GetArg(intptr_t index) const { return args_[index]; }
ObjectPtr GetClass() const { return GetArg(kClassIndex); }
ObjectPtr GetLength() const { return GetArg(kLengthIndex); }
ObjectPtr GetFieldOffset(intptr_t index) const {
return GetArg(kFieldsStartIndex + kFieldEntrySize * index + kOffsetIndex);
}
ObjectPtr GetValue(intptr_t index) const {
return GetArg(kFieldsStartIndex + kFieldEntrySize * index + kValueIndex);
}
// Amount of fields that have to be initialized.
const intptr_t field_count_;
// Pointer to the first materialization argument on the stack.
// The first argument is Class of the instance to materialize followed by
// Field, value pairs.
ObjectPtr* args_;
// Object materialized from this description.
const Object* object_;
DISALLOW_COPY_AND_ASSIGN(DeferredObject);
};
} // namespace dart
#endif // RUNTIME_VM_DEFERRED_OBJECTS_H_