b1c09ecd8f
Currently we have things called XPtr which are not what you get from ptr().
Old world:
handle->raw() returns RawObject* (tagged)
raw_obj->ptr() returns RawObject* (untagged)
After 6fe15f6df9:
handle->raw() returns ObjectPtr
obj_ptr->ptr() returns ObjectLayout*
New world:
handle->ptr() returns ObjectPtr
obj_ptr->untag() returns UntaggedObject*
TEST=ci
Change-Id: I6c7f34014cf20737607caaf84979838300d12df2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/149367
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
97 lines
3.4 KiB
C++
97 lines
3.4 KiB
C++
// Copyright (c) 2016, 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_HEAP_BECOME_H_
|
|
#define RUNTIME_VM_HEAP_BECOME_H_
|
|
|
|
#include "platform/atomic.h"
|
|
#include "vm/allocation.h"
|
|
#include "vm/raw_object.h"
|
|
|
|
namespace dart {
|
|
|
|
class Array;
|
|
|
|
// Objects that are a source in a become are tranformed into forwarding
|
|
// corpses pointing to the corresponding target. Forwarding corpses have the
|
|
// same heap sizes as the source object to ensure the heap remains walkable.
|
|
// If the heap sizes is small enough to be encoded in the size field of the
|
|
// header, a forwarding corpse consists only of a header and the target pointer.
|
|
// If the heap size is too big to be encoded in the header's size field, the
|
|
// word after the target pointer contains the size. This is the same
|
|
// representation as a FreeListElement.
|
|
class ForwardingCorpse {
|
|
public:
|
|
ObjectPtr target() const { return target_; }
|
|
void set_target(ObjectPtr target) { target_ = target; }
|
|
|
|
intptr_t HeapSize() {
|
|
intptr_t size = UntaggedObject::SizeTag::decode(tags_);
|
|
if (size != 0) return size;
|
|
return *SizeAddress();
|
|
}
|
|
|
|
static ForwardingCorpse* AsForwarder(uword addr, intptr_t size);
|
|
|
|
static void Init();
|
|
|
|
// Used to allocate class for forwarding corpses in Object::InitOnce.
|
|
class FakeInstance {
|
|
public:
|
|
FakeInstance() {}
|
|
static cpp_vtable vtable() { return 0; }
|
|
static intptr_t InstanceSize() { return 0; }
|
|
static intptr_t NextFieldOffset() { return -kWordSize; }
|
|
static const ClassId kClassId = kForwardingCorpse;
|
|
static bool IsInstance() { return true; }
|
|
|
|
private:
|
|
DISALLOW_ALLOCATION();
|
|
DISALLOW_COPY_AND_ASSIGN(FakeInstance);
|
|
};
|
|
|
|
private:
|
|
// This layout mirrors the layout of RawObject.
|
|
RelaxedAtomic<uword> tags_;
|
|
RelaxedAtomic<ObjectPtr> target_;
|
|
|
|
// Returns the address of the embedded size.
|
|
intptr_t* SizeAddress() const {
|
|
uword addr = reinterpret_cast<uword>(&target_) + kWordSize;
|
|
return reinterpret_cast<intptr_t*>(addr);
|
|
}
|
|
|
|
// ForwardingCorpses cannot be allocated. Instead references to them are
|
|
// created using the AsForwarder factory method.
|
|
DISALLOW_ALLOCATION();
|
|
DISALLOW_IMPLICIT_CONSTRUCTORS(ForwardingCorpse);
|
|
};
|
|
|
|
// TODO(johnmccutchan): Refactor this class so that it is not all static and
|
|
// provides utility methods for building the mapping of before and after.
|
|
class Become : public AllStatic {
|
|
public:
|
|
// Smalltalk's one-way bulk become (Array>>#elementsForwardIdentityTo:).
|
|
// Redirects all pointers to elements of 'before' to the corresponding element
|
|
// in 'after'. Every element in 'before' is guaranteed to be not reachable.
|
|
// Useful for atomically applying behavior and schema changes.
|
|
static void ElementsForwardIdentity(const Array& before, const Array& after);
|
|
|
|
// Convert and instance object into a dummy object,
|
|
// making the instance independent of its class.
|
|
// (used for morphic instances during reload).
|
|
static void MakeDummyObject(const Instance& instance);
|
|
|
|
// Update any references pointing to forwarding objects to point the
|
|
// forwarding objects' targets.
|
|
static void FollowForwardingPointers(Thread* thread);
|
|
|
|
private:
|
|
static void CrashDump(ObjectPtr before_obj, ObjectPtr after_obj);
|
|
};
|
|
|
|
} // namespace dart
|
|
|
|
#endif // RUNTIME_VM_HEAP_BECOME_H_
|