diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc index 907f501dc0c..1e9f6e034d9 100644 --- a/runtime/vm/interpreter.cc +++ b/runtime/vm/interpreter.cc @@ -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(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; diff --git a/runtime/vm/interpreter.h b/runtime/vm/interpreter.h index 994a1860d2f..a477c247d46 100644 --- a/runtime/vm/interpreter.h +++ b/runtime/vm/interpreter.h @@ -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; diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc index e235f5a8f6b..e649322e234 100644 --- a/runtime/vm/object.cc +++ b/runtime/vm/object.cc @@ -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(address)->tags_ = tags; + InitializeHeader(address, class_id, size); #if defined(HOST_HAS_FAST_WRITE_WRITE_FENCE) StoreStoreFence(); #endif diff --git a/runtime/vm/object.h b/runtime/vm/object.h index af6664eca56..977f79a1f82 100644 --- a/runtime/vm/object.h +++ b/runtime/vm/object.h @@ -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(address)->tags_ = tags; + } + static void InitializeObject(uword address, intptr_t id, intptr_t size,