mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 14:32:24 +00:00
f9a6a5bdd2
TEST=build Change-Id: I2834ef7cf7cb7c8770f8167a2438cbedcee5c623 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/292063 Commit-Queue: Ryan Macnak <rmacnak@google.com> Reviewed-by: Alexander Aprelev <aam@google.com>
256 lines
6.8 KiB
C++
256 lines
6.8 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_(nullptr) {}
|
|
|
|
intptr_t ArgumentCount() const {
|
|
return kFieldsStartIndex + kFieldEntrySize * field_count_;
|
|
}
|
|
|
|
ObjectPtr object();
|
|
|
|
// Fill object with actual field values.
|
|
void Fill();
|
|
|
|
private:
|
|
enum {
|
|
kClassIndex = 0,
|
|
|
|
// For contexts: number of context variables.
|
|
// For arrays and typed data objects: number of elements.
|
|
// For records: shape.
|
|
// -1 otherwise.
|
|
kLengthOrShapeIndex,
|
|
|
|
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 GetLengthOrShape() const { return GetArg(kLengthOrShapeIndex); }
|
|
|
|
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_
|