Files
sdk/runtime/vm/deferred_objects.h
T
fschneider@google.com 9709db7f76 VM: Add infrastructure to support deferred generation of unoptimized code.
Add deferred deoptimization instructions for return address, pc marker and
object pool pointer. This enables generating unoptimized code lazily
on deoptimization.

This CL does not change the way unoptimized code is generated or collected
yet, but just provides the mechanisms needed. This can be used to allow
code GC for the unoptimized code of optimized functions.

R=iposva@google.com

Review URL: https://codereview.chromium.org//1052563003

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@44934 260f80e4-7a28-3924-810f-c04153c831b5
2015-04-07 12:32:22 +00:00

267 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 VM_DEFERRED_OBJECTS_H_
#define VM_DEFERRED_OBJECTS_H_
#include "platform/globals.h"
namespace dart {
// Forward declarations.
class Object;
class RawObject;
class RawObject;
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(RawObject** slot, DeferredSlot* next)
: slot_(slot), next_(next) { }
virtual ~DeferredSlot() { }
RawObject** slot() const { return slot_; }
DeferredSlot* next() const { return next_; }
virtual void Materialize(DeoptContext* deopt_context) = 0;
private:
RawObject** const slot_;
DeferredSlot* const next_;
DISALLOW_COPY_AND_ASSIGN(DeferredSlot);
};
class DeferredDouble : public DeferredSlot {
public:
DeferredDouble(double value, RawObject** 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, RawObject** 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, RawObject** 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, RawObject** 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, RawObject** 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, RawObject** 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,
RawObject** 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, RawObject** 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, RawObject** 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<RawObject**>(args)),
object_(NULL) { }
intptr_t ArgumentCount() const {
return kFieldsStartIndex + kFieldEntrySize * field_count_;
}
RawObject* object();
// Fill object with actual field values.
void Fill();
private:
enum {
kClassIndex = 0,
kLengthIndex, // Number of context variables for contexts, -1 otherwise.
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();
RawObject* GetClass() const {
return args_[kClassIndex];
}
RawObject* GetLength() const {
return args_[kLengthIndex];
}
RawObject* GetFieldOffset(intptr_t index) const {
return args_[kFieldsStartIndex + kFieldEntrySize * index + kOffsetIndex];
}
RawObject* GetValue(intptr_t index) const {
return args_[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.
RawObject** args_;
// Object materialized from this description.
const Object* object_;
DISALLOW_COPY_AND_ASSIGN(DeferredObject);
};
} // namespace dart
#endif // VM_DEFERRED_OBJECTS_H_