[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:
Tess Strickland
2026-01-29 06:59:12 -08:00
committed by Commit Queue
parent 062382a80a
commit 62b145efbb
4 changed files with 63 additions and 74 deletions
-50
View File
@@ -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;
+33 -5
View File
@@ -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
View File
@@ -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
+29
View File
@@ -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,