[vm] Abstract out object header initialization.
Previously there were two separate implementations of the same initialization code, one in object.cc and one in interpreter.cc. Now they both use Object::InitializeHeader. Make TryAllocate a static method of Interpreter instead of a file-local function in interpreter.cc so that it gets access to the private method Object::InitializeHeader. TEST=ci (just code refactoring) Cq-Include-Trybots: luci.dart.try:vm-dyn-linux-debug-x64-try,vm-aot-dyn-linux-product-x64-try Change-Id: I4e042fbf0db84e02c88f7ca0f3e025723660001b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/476120 Reviewed-by: Alexander Markov <alexmarkov@google.com> Commit-Queue: Tess Strickland <sstrickl@google.com>
This commit is contained in:
committed by
Commit Queue
parent
062382a80a
commit
62b145efbb
@@ -231,56 +231,6 @@ DART_FORCE_INLINE static FunctionPtr FrameFunction(ObjectPtr* FP) {
|
||||
return Function::RawCast(FP[kKBCFunctionSlotFromFp]);
|
||||
}
|
||||
|
||||
DART_FORCE_INLINE static ObjectPtr InitializeHeader(uword addr,
|
||||
intptr_t class_id,
|
||||
intptr_t instance_size) {
|
||||
uint32_t tags = 0;
|
||||
ASSERT(class_id != kIllegalCid);
|
||||
tags = UntaggedObject::ClassIdTag::update(class_id, tags);
|
||||
tags = UntaggedObject::SizeTag::update(instance_size, tags);
|
||||
const bool is_old = false;
|
||||
tags = UntaggedObject::AlwaysSetBit::update(true, tags);
|
||||
tags = UntaggedObject::NotMarkedBit::update(true, tags);
|
||||
tags = UntaggedObject::OldAndNotRememberedBit::update(is_old, tags);
|
||||
tags = UntaggedObject::NewOrEvacuationCandidateBit::update(!is_old, tags);
|
||||
tags = UntaggedObject::ShallowImmutableBit::update(
|
||||
Object::ShouldHaveShallowImmutabilityBitSet(class_id), tags);
|
||||
tags = UntaggedObject::DeeplyImmutableBit::update(
|
||||
Object::ShouldHaveDeeplyImmutabilityBitSet(class_id), tags);
|
||||
#if defined(HASH_IN_OBJECT_HEADER)
|
||||
tags = UntaggedObject::HashTag::update(0, tags);
|
||||
#endif
|
||||
// Also writes zero in the hash_ field.
|
||||
*reinterpret_cast<uword*>(addr + Object::tags_offset()) = tags;
|
||||
return UntaggedObject::FromAddr(addr);
|
||||
}
|
||||
|
||||
DART_FORCE_INLINE static bool TryAllocate(Thread* thread,
|
||||
intptr_t class_id,
|
||||
intptr_t instance_size,
|
||||
ObjectPtr* result) {
|
||||
ASSERT(instance_size > 0);
|
||||
ASSERT(Utils::IsAligned(instance_size, kObjectAlignment));
|
||||
ASSERT(IsAllocatableInNewSpace(instance_size));
|
||||
|
||||
#if !defined(PRODUCT)
|
||||
auto* const class_table = thread->isolate_group()->class_table();
|
||||
if (UNLIKELY(class_table->ShouldTraceAllocationFor(class_id))) {
|
||||
// Fall back to the runtime for profiled allocation of classes.
|
||||
return false;
|
||||
}
|
||||
#endif // !defined(PRODUCT)
|
||||
|
||||
const uword top = thread->top();
|
||||
const intptr_t remaining = thread->end() - top;
|
||||
if (LIKELY(remaining >= instance_size)) {
|
||||
thread->set_top(top + instance_size);
|
||||
*result = InitializeHeader(top, class_id, instance_size);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LookupCache::Clear() {
|
||||
for (intptr_t i = 0; i < kNumEntries; i++) {
|
||||
entries_[i].receiver_cid = kIllegalCid;
|
||||
|
||||
@@ -8,19 +8,20 @@
|
||||
#include "vm/globals.h"
|
||||
#if defined(DART_DYNAMIC_MODULES)
|
||||
|
||||
#include "platform/utils.h"
|
||||
#include "vm/class_table.h"
|
||||
#include "vm/compiler/method_recognizer.h"
|
||||
#include "vm/constants_kbc.h"
|
||||
#include "vm/heap/spaces.h"
|
||||
#include "vm/isolate.h"
|
||||
#include "vm/object.h"
|
||||
#include "vm/tagged_pointer.h"
|
||||
#include "vm/thread.h"
|
||||
#include "vm/visitor.h"
|
||||
|
||||
namespace dart {
|
||||
|
||||
class Array;
|
||||
class Code;
|
||||
class InterpreterSetjmpBuffer;
|
||||
class Isolate;
|
||||
class ObjectPointerVisitor;
|
||||
class Thread;
|
||||
|
||||
class LookupCache : public ValueObject {
|
||||
public:
|
||||
@@ -250,6 +251,33 @@ class Interpreter {
|
||||
|
||||
ObjectPtr Run(Thread* thread, ObjectPtr* sp, bool rethrow_exception);
|
||||
|
||||
DART_FORCE_INLINE static bool TryAllocate(Thread* thread,
|
||||
intptr_t class_id,
|
||||
intptr_t instance_size,
|
||||
ObjectPtr* result) {
|
||||
ASSERT(instance_size > 0);
|
||||
ASSERT(Utils::IsAligned(instance_size, kObjectAlignment));
|
||||
ASSERT(IsAllocatableInNewSpace(instance_size));
|
||||
|
||||
#if !defined(PRODUCT)
|
||||
auto* const class_table = thread->isolate_group()->class_table();
|
||||
if (UNLIKELY(class_table->ShouldTraceAllocationFor(class_id))) {
|
||||
// Fall back to the runtime for profiled allocation of classes.
|
||||
return false;
|
||||
}
|
||||
#endif // !defined(PRODUCT)
|
||||
|
||||
const uword top = thread->top();
|
||||
const intptr_t remaining = thread->end() - top;
|
||||
if (LIKELY(remaining >= instance_size)) {
|
||||
thread->set_top(top + instance_size);
|
||||
Object::InitializeHeader(top, class_id, instance_size);
|
||||
*result = UntaggedObject::FromAddr(top);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(DEBUG)
|
||||
// Returns true if tracing of executed instructions is enabled.
|
||||
bool IsTracingExecution() const;
|
||||
|
||||
+1
-19
@@ -2966,25 +2966,7 @@ void Object::InitializeObject(uword address,
|
||||
}
|
||||
#endif
|
||||
}
|
||||
uword tags = 0;
|
||||
ASSERT(class_id != kIllegalCid);
|
||||
tags = UntaggedObject::ClassIdTag::update(class_id, tags);
|
||||
tags = UntaggedObject::SizeTag::update(size, tags);
|
||||
const bool is_old =
|
||||
(address & kNewObjectAlignmentOffset) == kOldObjectAlignmentOffset;
|
||||
tags = UntaggedObject::AlwaysSetBit::update(true, tags);
|
||||
tags = UntaggedObject::NotMarkedBit::update(true, tags);
|
||||
tags = UntaggedObject::OldAndNotRememberedBit::update(is_old, tags);
|
||||
tags = UntaggedObject::NewOrEvacuationCandidateBit::update(!is_old, tags);
|
||||
tags = UntaggedObject::ShallowImmutableBit::update(
|
||||
Object::ShouldHaveShallowImmutabilityBitSet(class_id), tags);
|
||||
tags = UntaggedObject::DeeplyImmutableBit::update(
|
||||
Object::ShouldHaveDeeplyImmutabilityBitSet(class_id), tags);
|
||||
#if defined(HASH_IN_OBJECT_HEADER)
|
||||
tags = UntaggedObject::HashTag::update(0, tags);
|
||||
#endif
|
||||
|
||||
reinterpret_cast<UntaggedObject*>(address)->tags_ = tags;
|
||||
InitializeHeader(address, class_id, size);
|
||||
#if defined(HOST_HAS_FAST_WRITE_WRITE_FENCE)
|
||||
StoreStoreFence();
|
||||
#endif
|
||||
|
||||
@@ -990,6 +990,35 @@ class Object {
|
||||
return -kWordSize;
|
||||
}
|
||||
|
||||
// Initialize the oject header for a freshly allocated object at [address]
|
||||
// of size [instance_size] with cid [class_id]. If the hash is stored in
|
||||
// the object header, it is initialized to 0.
|
||||
//
|
||||
// Whether the object is old or new is determined from the address,
|
||||
// see ObjectAlignment in pointer_tagging.h for details.
|
||||
DART_FORCE_INLINE static void InitializeHeader(uword address,
|
||||
intptr_t class_id,
|
||||
intptr_t instance_size) {
|
||||
uword tags = 0;
|
||||
ASSERT(class_id != kIllegalCid);
|
||||
tags = UntaggedObject::ClassIdTag::update(class_id, tags);
|
||||
tags = UntaggedObject::SizeTag::update(instance_size, tags);
|
||||
const bool is_old =
|
||||
(address & kNewObjectAlignmentOffset) == kOldObjectAlignmentOffset;
|
||||
tags = UntaggedObject::AlwaysSetBit::update(true, tags);
|
||||
tags = UntaggedObject::NotMarkedBit::update(true, tags);
|
||||
tags = UntaggedObject::OldAndNotRememberedBit::update(is_old, tags);
|
||||
tags = UntaggedObject::NewOrEvacuationCandidateBit::update(!is_old, tags);
|
||||
tags = UntaggedObject::ShallowImmutableBit::update(
|
||||
Object::ShouldHaveShallowImmutabilityBitSet(class_id), tags);
|
||||
tags = UntaggedObject::DeeplyImmutableBit::update(
|
||||
Object::ShouldHaveDeeplyImmutabilityBitSet(class_id), tags);
|
||||
#if defined(HASH_IN_OBJECT_HEADER)
|
||||
tags = UntaggedObject::HashTag::update(0, tags);
|
||||
#endif
|
||||
reinterpret_cast<UntaggedObject*>(address)->tags_ = tags;
|
||||
}
|
||||
|
||||
static void InitializeObject(uword address,
|
||||
intptr_t id,
|
||||
intptr_t size,
|
||||
|
||||
Reference in New Issue
Block a user