diff --git a/common.gypi b/common.gypi index 0c7c6b577d7fdf..6ef0d92eeada98 100644 --- a/common.gypi +++ b/common.gypi @@ -37,7 +37,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.9', + 'v8_embedder_string': '-node.10', ##### V8 defaults for Node.js ##### diff --git a/deps/v8/BUILD.gn b/deps/v8/BUILD.gn index fddd525297773e..7a50b192f0a9eb 100644 --- a/deps/v8/BUILD.gn +++ b/deps/v8/BUILD.gn @@ -2276,6 +2276,8 @@ v8_source_set("v8_base") { "src/objects/code.h", "src/objects/compilation-cache-inl.h", "src/objects/compilation-cache.h", + "src/objects/compressed-slots-inl.h", + "src/objects/compressed-slots.h", "src/objects/data-handler.h", "src/objects/debug-objects-inl.h", "src/objects/debug-objects.cc", diff --git a/deps/v8/src/arm64/macro-assembler-arm64-inl.h b/deps/v8/src/arm64/macro-assembler-arm64-inl.h index ae055f40abd420..be6cd4c933ad28 100644 --- a/deps/v8/src/arm64/macro-assembler-arm64-inl.h +++ b/deps/v8/src/arm64/macro-assembler-arm64-inl.h @@ -1060,7 +1060,11 @@ void TurboAssembler::SmiUntag(Register dst, const MemOperand& src) { } } else { DCHECK(SmiValuesAre31Bits()); +#ifdef V8_COMPRESS_POINTERS + Ldrsw(dst, src); +#else Ldr(dst, src); +#endif SmiUntag(dst); } } diff --git a/deps/v8/src/arm64/macro-assembler-arm64.cc b/deps/v8/src/arm64/macro-assembler-arm64.cc index ad0ed8894ab0ff..79688d709b3d88 100644 --- a/deps/v8/src/arm64/macro-assembler-arm64.cc +++ b/deps/v8/src/arm64/macro-assembler-arm64.cc @@ -2813,11 +2813,7 @@ void TurboAssembler::StoreTaggedField(const Register& value, const MemOperand& dst_field_operand) { #ifdef V8_COMPRESS_POINTERS RecordComment("[ StoreTagged"); - // Use temporary register to zero out and don't trash value register - UseScratchRegisterScope temps(this); - Register compressed_value = temps.AcquireX(); - Uxtw(compressed_value, value); - Str(compressed_value, dst_field_operand); + Str(value.W(), dst_field_operand); RecordComment("]"); #else Str(value, dst_field_operand); @@ -2827,18 +2823,15 @@ void TurboAssembler::StoreTaggedField(const Register& value, void TurboAssembler::DecompressTaggedSigned(const Register& destination, const MemOperand& field_operand) { RecordComment("[ DecompressTaggedSigned"); - // TODO(solanes): use Ldrsw instead of Ldr,SXTW once kTaggedSize is shrinked - Ldr(destination, field_operand); - Sxtw(destination, destination); + Ldrsw(destination, field_operand); RecordComment("]"); } void TurboAssembler::DecompressTaggedPointer(const Register& destination, const MemOperand& field_operand) { RecordComment("[ DecompressTaggedPointer"); - // TODO(solanes): use Ldrsw instead of Ldr,SXTW once kTaggedSize is shrinked - Ldr(destination, field_operand); - Add(destination, kRootRegister, Operand(destination, SXTW)); + Ldrsw(destination, field_operand); + Add(destination, kRootRegister, destination); RecordComment("]"); } @@ -2846,8 +2839,7 @@ void TurboAssembler::DecompressAnyTagged(const Register& destination, const MemOperand& field_operand) { RecordComment("[ DecompressAnyTagged"); UseScratchRegisterScope temps(this); - // TODO(solanes): use Ldrsw instead of Ldr,SXTW once kTaggedSize is shrinked - Ldr(destination, field_operand); + Ldrsw(destination, field_operand); // Branchlessly compute |masked_root|: // masked_root = HAS_SMI_TAG(destination) ? 0 : kRootRegister; STATIC_ASSERT((kSmiTagSize == 1) && (kSmiTag == 0)); @@ -2857,7 +2849,7 @@ void TurboAssembler::DecompressAnyTagged(const Register& destination, And(masked_root, masked_root, kRootRegister); // Now this add operation will either leave the value unchanged if it is a smi // or add the isolate root if it is a heap object. - Add(destination, masked_root, Operand(destination, SXTW)); + Add(destination, masked_root, destination); RecordComment("]"); } diff --git a/deps/v8/src/base/macros.h b/deps/v8/src/base/macros.h index 14c69d3fc2d485..1276805182084b 100644 --- a/deps/v8/src/base/macros.h +++ b/deps/v8/src/base/macros.h @@ -318,7 +318,7 @@ V8_INLINE A implicit_cast(A x) { #define V8PRIdPTR V8_PTR_PREFIX "d" #define V8PRIuPTR V8_PTR_PREFIX "u" -#ifdef V8_TARGET_ARCH_64_BIT +#if V8_TARGET_ARCH_64_BIT #define V8_PTR_HEX_DIGITS 12 #define V8PRIxPTR_FMT "0x%012" V8PRIxPTR #else diff --git a/deps/v8/src/bootstrapper.h b/deps/v8/src/bootstrapper.h index 1667d6018af1c9..329bf57c509f04 100644 --- a/deps/v8/src/bootstrapper.h +++ b/deps/v8/src/bootstrapper.h @@ -8,7 +8,6 @@ #include "src/heap/factory.h" #include "src/objects/fixed-array.h" #include "src/objects/shared-function-info.h" -#include "src/objects/slots.h" #include "src/snapshot/natives.h" #include "src/visitors.h" diff --git a/deps/v8/src/builtins/arm64/builtins-arm64.cc b/deps/v8/src/builtins/arm64/builtins-arm64.cc index 9c7397897a800a..35ed82a83e035d 100644 --- a/deps/v8/src/builtins/arm64/builtins-arm64.cc +++ b/deps/v8/src/builtins/arm64/builtins-arm64.cc @@ -2555,7 +2555,7 @@ void Generate_PushBoundArguments(MacroAssembler* masm) { __ SlotAddress(copy_to, argc); __ Add(argc, argc, bound_argc); // Update argc to include bound arguments. - __ Lsl(counter, bound_argc, kSystemPointerSizeLog2); + __ Lsl(counter, bound_argc, kTaggedSizeLog2); __ Bind(&loop); __ Sub(counter, counter, kTaggedSize); __ LoadAnyTaggedField(scratch, MemOperand(bound_argv, counter)); diff --git a/deps/v8/src/heap/heap-write-barrier-inl.h b/deps/v8/src/heap/heap-write-barrier-inl.h index 63d16ca82dc9d1..9b2d3a8fa31231 100644 --- a/deps/v8/src/heap/heap-write-barrier-inl.h +++ b/deps/v8/src/heap/heap-write-barrier-inl.h @@ -15,6 +15,7 @@ // elsewhere. #include "src/isolate.h" #include "src/objects/code.h" +#include "src/objects/compressed-slots-inl.h" #include "src/objects/fixed-array.h" #include "src/objects/heap-object.h" #include "src/objects/maybe-object-inl.h" diff --git a/deps/v8/src/heap/heap.h b/deps/v8/src/heap/heap.h index 7f687e8fdf3c92..29aa5fa9fb8d56 100644 --- a/deps/v8/src/heap/heap.h +++ b/deps/v8/src/heap/heap.h @@ -2347,6 +2347,20 @@ class HeapObjectAllocationTracker { virtual ~HeapObjectAllocationTracker() = default; }; +template +T ForwardingAddress(T heap_obj) { + MapWord map_word = heap_obj->map_word(); + + if (map_word.IsForwardingAddress()) { + return T::cast(map_word.ToForwardingAddress()); + } else if (Heap::InFromPage(heap_obj)) { + return T(); + } else { + // TODO(ulan): Support minor mark-compactor here. + return heap_obj; + } +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/heap/incremental-marking.cc b/deps/v8/src/heap/incremental-marking.cc index 2a665394d3469e..3332eff38d713c 100644 --- a/deps/v8/src/heap/incremental-marking.cc +++ b/deps/v8/src/heap/incremental-marking.cc @@ -609,22 +609,6 @@ void IncrementalMarking::UpdateMarkingWorklistAfterScavenge() { UpdateWeakReferencesAfterScavenge(); } -namespace { -template -T ForwardingAddress(T heap_obj) { - MapWord map_word = heap_obj->map_word(); - - if (map_word.IsForwardingAddress()) { - return T::cast(map_word.ToForwardingAddress()); - } else if (Heap::InFromPage(heap_obj)) { - return T(); - } else { - // TODO(ulan): Support minor mark-compactor here. - return heap_obj; - } -} -} // namespace - void IncrementalMarking::UpdateWeakReferencesAfterScavenge() { weak_objects_->weak_references.Update( [](std::pair slot_in, diff --git a/deps/v8/src/heap/scavenger-inl.h b/deps/v8/src/heap/scavenger-inl.h index 1ac96b7362fa31..4736519099f402 100644 --- a/deps/v8/src/heap/scavenger-inl.h +++ b/deps/v8/src/heap/scavenger-inl.h @@ -480,6 +480,21 @@ void ScavengeVisitor::VisitPointersImpl(HeapObject host, TSlot start, } } +int ScavengeVisitor::VisitEphemeronHashTable(Map map, + EphemeronHashTable table) { + // Register table with the scavenger, so it can take care of the weak keys + // later. This allows to only iterate the tables' values, which are treated + // as strong independetly of whether the key is live. + scavenger_->AddEphemeronHashTable(table); + for (int i = 0; i < table->Capacity(); i++) { + ObjectSlot value_slot = + table->RawFieldOfElementAt(EphemeronHashTable::EntryToValueIndex(i)); + VisitPointer(table, value_slot); + } + + return table->SizeFromMap(map); +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/heap/scavenger.cc b/deps/v8/src/heap/scavenger.cc index df0ed8886e26dd..b6403d472f4451 100644 --- a/deps/v8/src/heap/scavenger.cc +++ b/deps/v8/src/heap/scavenger.cc @@ -151,11 +151,25 @@ class IterateAndScavengePromotedObjectsVisitor final : public ObjectVisitor { const bool record_slots_; }; -static bool IsUnscavengedHeapObject(Heap* heap, FullObjectSlot p) { - return Heap::InFromPage(*p) && - !HeapObject::cast(*p)->map_word().IsForwardingAddress(); +namespace { + +V8_INLINE bool IsUnscavengedHeapObject(Heap* heap, Object object) { + return Heap::InFromPage(object) && + !HeapObject::cast(object)->map_word().IsForwardingAddress(); +} + +// Same as IsUnscavengedHeapObject() above but specialized for HeapObjects. +V8_INLINE bool IsUnscavengedHeapObject(Heap* heap, HeapObject heap_object) { + return Heap::InFromPage(heap_object) && + !heap_object->map_word().IsForwardingAddress(); +} + +bool IsUnscavengedHeapObjectSlot(Heap* heap, FullObjectSlot p) { + return IsUnscavengedHeapObject(heap, *p); } +} // namespace + class ScavengeWeakObjectRetainer : public WeakObjectRetainer { public: Object RetainAs(Object object) override { @@ -185,9 +199,10 @@ void ScavengerCollector::CollectGarbage() { OneshotBarrier barrier(base::TimeDelta::FromMilliseconds(kMaxWaitTimeMs)); Scavenger::CopiedList copied_list(num_scavenge_tasks); Scavenger::PromotionList promotion_list(num_scavenge_tasks); + EphemeronTableList ephemeron_table_list(num_scavenge_tasks); for (int i = 0; i < num_scavenge_tasks; i++) { scavengers[i] = new Scavenger(this, heap_, is_logging, &copied_list, - &promotion_list, i); + &promotion_list, &ephemeron_table_list, i); job.AddTask(new ScavengingTask(heap_, scavengers[i], &barrier)); } @@ -235,7 +250,7 @@ void ScavengerCollector::CollectGarbage() { TRACE_GC(heap_->tracer(), GCTracer::Scope::SCAVENGER_SCAVENGE_WEAK_GLOBAL_HANDLES_PROCESS); isolate_->global_handles()->MarkYoungWeakUnmodifiedObjectsPending( - &IsUnscavengedHeapObject); + &IsUnscavengedHeapObjectSlot); isolate_->global_handles()->IterateYoungWeakUnmodifiedRootsForFinalizers( &root_scavenge_visitor); scavengers[kMainThreadId]->Process(); @@ -244,7 +259,7 @@ void ScavengerCollector::CollectGarbage() { DCHECK(promotion_list.IsEmpty()); isolate_->global_handles() ->IterateYoungWeakUnmodifiedRootsForPhantomHandles( - &root_scavenge_visitor, &IsUnscavengedHeapObject); + &root_scavenge_visitor, &IsUnscavengedHeapObjectSlot); } { @@ -280,8 +295,7 @@ void ScavengerCollector::CollectGarbage() { } } - ScavengeWeakObjectRetainer weak_object_retainer; - heap_->ProcessYoungWeakReferences(&weak_object_retainer); + ProcessWeakReferences(&ephemeron_table_list); // Set age mark. heap_->new_space_->set_age_mark(heap_->new_space()->top()); @@ -349,11 +363,12 @@ int ScavengerCollector::NumberOfScavengeTasks() { Scavenger::Scavenger(ScavengerCollector* collector, Heap* heap, bool is_logging, CopiedList* copied_list, PromotionList* promotion_list, - int task_id) + EphemeronTableList* ephemeron_table_list, int task_id) : collector_(collector), heap_(heap), promotion_list_(promotion_list, task_id), copied_list_(copied_list, task_id), + ephemeron_table_list_(ephemeron_table_list, task_id), local_pretenuring_feedback_(kInitialLocalPretenuringFeedbackCapacity), copied_size_(0), promoted_size_(0), @@ -440,12 +455,45 @@ void Scavenger::Process(OneshotBarrier* barrier) { } while (!done); } +void ScavengerCollector::ProcessWeakReferences( + EphemeronTableList* ephemeron_table_list) { + ScavengeWeakObjectRetainer weak_object_retainer; + heap_->ProcessYoungWeakReferences(&weak_object_retainer); + ClearYoungEphemerons(ephemeron_table_list); +} + +// Clears ephemerons contained in {EphemeronHashTable}s in young generation. +void ScavengerCollector::ClearYoungEphemerons( + EphemeronTableList* ephemeron_table_list) { + ephemeron_table_list->Iterate([this](EphemeronHashTable table) { + for (int i = 0; i < table->Capacity(); i++) { + ObjectSlot key_slot = + table->RawFieldOfElementAt(EphemeronHashTable::EntryToIndex(i)); + Object key = *key_slot; + if (key->IsHeapObject()) { + if (IsUnscavengedHeapObject(heap_, HeapObject::cast(key))) { + table->RemoveEntry(i); + } else { + HeapObject forwarded = ForwardingAddress(HeapObject::cast(key)); + HeapObjectReference::Update(HeapObjectSlot(key_slot), forwarded); + } + } + } + }); + ephemeron_table_list->Clear(); +} + void Scavenger::Finalize() { heap()->MergeAllocationSitePretenuringFeedback(local_pretenuring_feedback_); heap()->IncrementSemiSpaceCopiedObjectSize(copied_size_); heap()->IncrementPromotedObjectsSize(promoted_size_); collector_->MergeSurvivingNewLargeObjects(surviving_new_large_objects_); allocator_.Finalize(); + ephemeron_table_list_.FlushToGlobal(); +} + +void Scavenger::AddEphemeronHashTable(EphemeronHashTable table) { + ephemeron_table_list_.Push(table); } void RootScavengeVisitor::VisitRootPointer(Root root, const char* description, diff --git a/deps/v8/src/heap/scavenger.h b/deps/v8/src/heap/scavenger.h index e122ab8cdf81c6..b33713ec3f1125 100644 --- a/deps/v8/src/heap/scavenger.h +++ b/deps/v8/src/heap/scavenger.h @@ -27,6 +27,10 @@ using SurvivingNewLargeObjectsMap = std::unordered_map; using SurvivingNewLargeObjectMapEntry = std::pair; +constexpr int kEphemeronTableListSegmentSize = 128; +using EphemeronTableList = + Worklist; + class ScavengerCollector { public: static const int kMaxScavengerTasks = 8; @@ -42,6 +46,8 @@ class ScavengerCollector { int NumberOfScavengeTasks(); + void ProcessWeakReferences(EphemeronTableList* ephemeron_table_list); + void ClearYoungEphemerons(EphemeronTableList* ephemeron_table_list); void HandleSurvivingNewLargeObjects(); Isolate* const isolate_; @@ -109,10 +115,9 @@ class Scavenger { static const int kCopiedListSegmentSize = 256; using CopiedList = Worklist; - Scavenger(ScavengerCollector* collector, Heap* heap, bool is_logging, CopiedList* copied_list, PromotionList* promotion_list, - int task_id); + EphemeronTableList* ephemeron_table_list, int task_id); // Entry point for scavenging an old generation page. For scavenging single // objects see RootScavengingVisitor and ScavengeVisitor below. @@ -125,6 +130,8 @@ class Scavenger { // Finalize the Scavenger. Needs to be called from the main thread. void Finalize(); + void AddEphemeronHashTable(EphemeronHashTable table); + size_t bytes_copied() const { return copied_size_; } size_t bytes_promoted() const { return promoted_size_; } @@ -199,6 +206,7 @@ class Scavenger { Heap* const heap_; PromotionList::View promotion_list_; CopiedList::View copied_list_; + EphemeronTableList::View ephemeron_table_list_; Heap::PretenuringFeedbackMap local_pretenuring_feedback_; size_t copied_size_; size_t promoted_size_; @@ -242,6 +250,7 @@ class ScavengeVisitor final : public NewSpaceVisitor { V8_INLINE void VisitCodeTarget(Code host, RelocInfo* rinfo) final; V8_INLINE void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) final; + V8_INLINE int VisitEphemeronHashTable(Map map, EphemeronHashTable object); private: template diff --git a/deps/v8/src/heap/slot-set.h b/deps/v8/src/heap/slot-set.h index 2d9fb327bed486..7870e57b5683c8 100644 --- a/deps/v8/src/heap/slot-set.h +++ b/deps/v8/src/heap/slot-set.h @@ -11,13 +11,10 @@ #include "src/allocation.h" #include "src/base/atomic-utils.h" #include "src/base/bits.h" +#include "src/objects/compressed-slots.h" #include "src/objects/slots.h" #include "src/utils.h" -#ifdef V8_COMPRESS_POINTERS -#include "src/ptr-compr.h" -#endif - namespace v8 { namespace internal { diff --git a/deps/v8/src/heap/worklist.h b/deps/v8/src/heap/worklist.h index c086b87e5995cd..82a278a0429254 100644 --- a/deps/v8/src/heap/worklist.h +++ b/deps/v8/src/heap/worklist.h @@ -51,6 +51,8 @@ class Worklist { return worklist_->LocalPushSegmentSize(task_id_); } + void FlushToGlobal() { worklist_->FlushToGlobal(task_id_); } + private: Worklist* worklist_; int task_id_; diff --git a/deps/v8/src/isolate.cc b/deps/v8/src/isolate.cc index 8187284ba83db9..b30c34c2f5fe6b 100644 --- a/deps/v8/src/isolate.cc +++ b/deps/v8/src/isolate.cc @@ -2786,7 +2786,7 @@ Isolate* Isolate::New(IsolateAllocationMode mode) { // Construct Isolate object in the allocated memory. void* isolate_ptr = isolate_allocator->isolate_memory(); Isolate* isolate = new (isolate_ptr) Isolate(std::move(isolate_allocator)); -#ifdef V8_TARGET_ARCH_64_BIT +#if V8_TARGET_ARCH_64_BIT DCHECK_IMPLIES( mode == IsolateAllocationMode::kInV8Heap, IsAligned(isolate->isolate_root(), kPtrComprIsolateRootAlignment)); diff --git a/deps/v8/src/objects-body-descriptors-inl.h b/deps/v8/src/objects-body-descriptors-inl.h index 919953bb61db58..a5c6a7d35f361e 100644 --- a/deps/v8/src/objects-body-descriptors-inl.h +++ b/deps/v8/src/objects-body-descriptors-inl.h @@ -14,7 +14,6 @@ #include "src/objects/js-collection.h" #include "src/objects/js-weak-refs.h" #include "src/objects/oddball.h" -#include "src/objects/slots.h" #include "src/reloc-info.h" #include "src/transitions.h" #include "src/wasm/wasm-objects-inl.h" diff --git a/deps/v8/src/objects.h b/deps/v8/src/objects.h index 4a9b5f33e29445..d7cb4f39d0e1e2 100644 --- a/deps/v8/src/objects.h +++ b/deps/v8/src/objects.h @@ -26,10 +26,6 @@ #include "src/property-details.h" #include "src/utils.h" -#ifdef V8_COMPRESS_POINTERS -#include "src/ptr-compr.h" -#endif - // Has to be the last include (doesn't have include guards): #include "src/objects/object-macros.h" diff --git a/deps/v8/src/objects/compressed-slots-inl.h b/deps/v8/src/objects/compressed-slots-inl.h new file mode 100644 index 00000000000000..9c55de9ae687e4 --- /dev/null +++ b/deps/v8/src/objects/compressed-slots-inl.h @@ -0,0 +1,169 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_OBJECTS_COMPRESSED_SLOTS_INL_H_ +#define V8_OBJECTS_COMPRESSED_SLOTS_INL_H_ + +#ifdef V8_COMPRESS_POINTERS + +#include "src/objects/compressed-slots.h" +#include "src/objects/heap-object-inl.h" +#include "src/objects/maybe-object-inl.h" +#include "src/ptr-compr-inl.h" + +namespace v8 { +namespace internal { + +// +// CompressedObjectSlot implementation. +// + +CompressedObjectSlot::CompressedObjectSlot(Object* object) + : SlotBase(reinterpret_cast
(&object->ptr_)) {} + +Object CompressedObjectSlot::operator*() const { + Tagged_t value = *location(); + return Object(DecompressTaggedAny(address(), value)); +} + +void CompressedObjectSlot::store(Object value) const { + *location() = CompressTagged(value->ptr()); +} + +Object CompressedObjectSlot::Acquire_Load() const { + AtomicTagged_t value = AsAtomicTagged::Acquire_Load(location()); + return Object(DecompressTaggedAny(address(), value)); +} + +Object CompressedObjectSlot::Relaxed_Load() const { + AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location()); + return Object(DecompressTaggedAny(address(), value)); +} + +void CompressedObjectSlot::Relaxed_Store(Object value) const { + Tagged_t ptr = CompressTagged(value->ptr()); + AsAtomicTagged::Relaxed_Store(location(), ptr); +} + +void CompressedObjectSlot::Release_Store(Object value) const { + Tagged_t ptr = CompressTagged(value->ptr()); + AsAtomicTagged::Release_Store(location(), ptr); +} + +Object CompressedObjectSlot::Release_CompareAndSwap(Object old, + Object target) const { + Tagged_t old_ptr = CompressTagged(old->ptr()); + Tagged_t target_ptr = CompressTagged(target->ptr()); + Tagged_t result = + AsAtomicTagged::Release_CompareAndSwap(location(), old_ptr, target_ptr); + return Object(DecompressTaggedAny(address(), result)); +} + +// +// CompressedMapWordSlot implementation. +// + +bool CompressedMapWordSlot::contains_value(Address raw_value) const { + AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location()); + return static_cast(value) == + static_cast(static_cast(raw_value)); +} + +Object CompressedMapWordSlot::operator*() const { + Tagged_t value = *location(); + return Object(DecompressTaggedPointer(address(), value)); +} + +void CompressedMapWordSlot::store(Object value) const { + *location() = CompressTagged(value.ptr()); +} + +Object CompressedMapWordSlot::Relaxed_Load() const { + AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location()); + return Object(DecompressTaggedPointer(address(), value)); +} + +void CompressedMapWordSlot::Relaxed_Store(Object value) const { + Tagged_t ptr = CompressTagged(value.ptr()); + AsAtomicTagged::Relaxed_Store(location(), ptr); +} + +Object CompressedMapWordSlot::Acquire_Load() const { + AtomicTagged_t value = AsAtomicTagged::Acquire_Load(location()); + return Object(DecompressTaggedPointer(address(), value)); +} + +void CompressedMapWordSlot::Release_Store(Object value) const { + Tagged_t ptr = CompressTagged(value->ptr()); + AsAtomicTagged::Release_Store(location(), ptr); +} + +Object CompressedMapWordSlot::Release_CompareAndSwap(Object old, + Object target) const { + Tagged_t old_ptr = CompressTagged(old->ptr()); + Tagged_t target_ptr = CompressTagged(target->ptr()); + Tagged_t result = + AsAtomicTagged::Release_CompareAndSwap(location(), old_ptr, target_ptr); + return Object(DecompressTaggedPointer(address(), result)); +} + +// +// CompressedMaybeObjectSlot implementation. +// + +MaybeObject CompressedMaybeObjectSlot::operator*() const { + Tagged_t value = *location(); + return MaybeObject(DecompressTaggedAny(address(), value)); +} + +void CompressedMaybeObjectSlot::store(MaybeObject value) const { + *location() = CompressTagged(value->ptr()); +} + +MaybeObject CompressedMaybeObjectSlot::Relaxed_Load() const { + AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location()); + return MaybeObject(DecompressTaggedAny(address(), value)); +} + +void CompressedMaybeObjectSlot::Relaxed_Store(MaybeObject value) const { + Tagged_t ptr = CompressTagged(value->ptr()); + AsAtomicTagged::Relaxed_Store(location(), ptr); +} + +void CompressedMaybeObjectSlot::Release_CompareAndSwap( + MaybeObject old, MaybeObject target) const { + Tagged_t old_ptr = CompressTagged(old->ptr()); + Tagged_t target_ptr = CompressTagged(target->ptr()); + AsAtomicTagged::Release_CompareAndSwap(location(), old_ptr, target_ptr); +} + +// +// CompressedHeapObjectSlot implementation. +// + +HeapObjectReference CompressedHeapObjectSlot::operator*() const { + Tagged_t value = *location(); + return HeapObjectReference(DecompressTaggedPointer(address(), value)); +} + +void CompressedHeapObjectSlot::store(HeapObjectReference value) const { + *location() = CompressTagged(value.ptr()); +} + +HeapObject CompressedHeapObjectSlot::ToHeapObject() const { + Tagged_t value = *location(); + DCHECK_EQ(value & kHeapObjectTagMask, kHeapObjectTag); + return HeapObject::cast(Object(DecompressTaggedPointer(address(), value))); +} + +void CompressedHeapObjectSlot::StoreHeapObject(HeapObject value) const { + *location() = CompressTagged(value->ptr()); +} + +} // namespace internal +} // namespace v8 + +#endif // V8_COMPRESS_POINTERS + +#endif // V8_OBJECTS_COMPRESSED_SLOTS_INL_H_ diff --git a/deps/v8/src/objects/compressed-slots.h b/deps/v8/src/objects/compressed-slots.h new file mode 100644 index 00000000000000..45df733caf73e5 --- /dev/null +++ b/deps/v8/src/objects/compressed-slots.h @@ -0,0 +1,141 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_OBJECTS_COMPRESSED_SLOTS_H_ +#define V8_OBJECTS_COMPRESSED_SLOTS_H_ + +#ifdef V8_COMPRESS_POINTERS + +#include "src/objects/slots.h" + +namespace v8 { +namespace internal { + +// A CompressedObjectSlot instance describes a kTaggedSize-sized field ("slot") +// holding a compressed tagged pointer (smi or heap object). +// Its address() is the address of the slot. +// The slot's contents can be read and written using operator* and store(). +class CompressedObjectSlot : public SlotBase { + public: + using TObject = Object; + using THeapObjectSlot = CompressedHeapObjectSlot; + + static constexpr bool kCanBeWeak = false; + + CompressedObjectSlot() : SlotBase(kNullAddress) {} + explicit CompressedObjectSlot(Address ptr) : SlotBase(ptr) {} + explicit CompressedObjectSlot(Address* ptr) + : SlotBase(reinterpret_cast
(ptr)) {} + inline explicit CompressedObjectSlot(Object* object); + explicit CompressedObjectSlot(Object const* const* ptr) + : SlotBase(reinterpret_cast
(ptr)) {} + template + explicit CompressedObjectSlot(SlotBase slot) + : SlotBase(slot.address()) {} + + inline Object operator*() const; + inline void store(Object value) const; + + inline Object Acquire_Load() const; + inline Object Relaxed_Load() const; + inline void Relaxed_Store(Object value) const; + inline void Release_Store(Object value) const; + inline Object Release_CompareAndSwap(Object old, Object target) const; +}; + +// A CompressedMapWordSlot instance describes a kTaggedSize-sized map-word field +// ("slot") of heap objects holding a compressed tagged pointer or a Smi +// representing forwaring pointer value. +// This slot kind is similar to CompressedObjectSlot but decompression of +// forwarding pointer is different. +// Its address() is the address of the slot. +// The slot's contents can be read and written using operator* and store(). +class CompressedMapWordSlot : public SlotBase { + public: + using TObject = Object; + + static constexpr bool kCanBeWeak = false; + + CompressedMapWordSlot() : SlotBase(kNullAddress) {} + explicit CompressedMapWordSlot(Address ptr) : SlotBase(ptr) {} + + // Compares memory representation of a value stored in the slot with given + // raw value without decompression. + inline bool contains_value(Address raw_value) const; + + inline Object operator*() const; + inline void store(Object value) const; + + inline Object Relaxed_Load() const; + inline void Relaxed_Store(Object value) const; + + inline Object Acquire_Load() const; + inline void Release_Store(Object value) const; + inline Object Release_CompareAndSwap(Object old, Object target) const; +}; + +// A CompressedMaybeObjectSlot instance describes a kTaggedSize-sized field +// ("slot") holding a possibly-weak compressed tagged pointer +// (think: MaybeObject). +// Its address() is the address of the slot. +// The slot's contents can be read and written using operator* and store(). +class CompressedMaybeObjectSlot + : public SlotBase { + public: + using TObject = MaybeObject; + using THeapObjectSlot = CompressedHeapObjectSlot; + + static constexpr bool kCanBeWeak = true; + + CompressedMaybeObjectSlot() : SlotBase(kNullAddress) {} + explicit CompressedMaybeObjectSlot(Address ptr) : SlotBase(ptr) {} + explicit CompressedMaybeObjectSlot(Object* ptr) + : SlotBase(reinterpret_cast
(ptr)) {} + explicit CompressedMaybeObjectSlot(MaybeObject* ptr) + : SlotBase(reinterpret_cast
(ptr)) {} + template + explicit CompressedMaybeObjectSlot( + SlotBase slot) + : SlotBase(slot.address()) {} + + inline MaybeObject operator*() const; + inline void store(MaybeObject value) const; + + inline MaybeObject Relaxed_Load() const; + inline void Relaxed_Store(MaybeObject value) const; + inline void Release_CompareAndSwap(MaybeObject old, MaybeObject target) const; +}; + +// A CompressedHeapObjectSlot instance describes a kTaggedSize-sized field +// ("slot") holding a weak or strong compressed pointer to a heap object (think: +// HeapObjectReference). +// Its address() is the address of the slot. +// The slot's contents can be read and written using operator* and store(). +// In case it is known that that slot contains a strong heap object pointer, +// ToHeapObject() can be used to retrieve that heap object. +class CompressedHeapObjectSlot + : public SlotBase { + public: + CompressedHeapObjectSlot() : SlotBase(kNullAddress) {} + explicit CompressedHeapObjectSlot(Address ptr) : SlotBase(ptr) {} + explicit CompressedHeapObjectSlot(Object* ptr) + : SlotBase(reinterpret_cast
(ptr)) {} + template + explicit CompressedHeapObjectSlot(SlotBase slot) + : SlotBase(slot.address()) {} + + inline HeapObjectReference operator*() const; + inline void store(HeapObjectReference value) const; + + inline HeapObject ToHeapObject() const; + + inline void StoreHeapObject(HeapObject value) const; +}; + +} // namespace internal +} // namespace v8 + +#endif // V8_COMPRESS_POINTERS + +#endif // V8_OBJECTS_COMPRESSED_SLOTS_H_ diff --git a/deps/v8/src/objects/embedder-data-array-inl.h b/deps/v8/src/objects/embedder-data-array-inl.h index 6519427b7a9d43..34f22b1115d986 100644 --- a/deps/v8/src/objects/embedder-data-array-inl.h +++ b/deps/v8/src/objects/embedder-data-array-inl.h @@ -9,7 +9,6 @@ #include "src/objects/instance-type-inl.h" #include "src/objects/maybe-object-inl.h" -#include "src/objects/slots.h" // Has to be the last include (doesn't have include guards): #include "src/objects/object-macros.h" diff --git a/deps/v8/src/objects/embedder-data-slot.h b/deps/v8/src/objects/embedder-data-slot.h index e0c95623754d06..19bef3d170d4a0 100644 --- a/deps/v8/src/objects/embedder-data-slot.h +++ b/deps/v8/src/objects/embedder-data-slot.h @@ -36,10 +36,10 @@ class EmbedderDataSlot V8_INLINE EmbedderDataSlot(EmbedderDataArray array, int entry_index); V8_INLINE EmbedderDataSlot(JSObject object, int embedder_field_index); -#ifdef V8_TARGET_LITTLE_ENDIAN - static constexpr int kTaggedPayloadOffset = 0; -#else +#if defined(V8_TARGET_BIG_ENDIAN) && defined(V8_COMPRESS_POINTERS) static constexpr int kTaggedPayloadOffset = kTaggedSize; +#else + static constexpr int kTaggedPayloadOffset = 0; #endif #ifdef V8_COMPRESS_POINTERS diff --git a/deps/v8/src/objects/fixed-array-inl.h b/deps/v8/src/objects/fixed-array-inl.h index 1614b6a53627c7..dfb34102ddf20b 100644 --- a/deps/v8/src/objects/fixed-array-inl.h +++ b/deps/v8/src/objects/fixed-array-inl.h @@ -13,6 +13,7 @@ #include "src/heap/heap-write-barrier-inl.h" #include "src/objects-inl.h" #include "src/objects/bigint.h" +#include "src/objects/compressed-slots.h" #include "src/objects/heap-number-inl.h" #include "src/objects/map.h" #include "src/objects/maybe-object-inl.h" diff --git a/deps/v8/src/objects/fixed-array.h b/deps/v8/src/objects/fixed-array.h index a4c9d50e2c53fc..2dc99de6da4d30 100644 --- a/deps/v8/src/objects/fixed-array.h +++ b/deps/v8/src/objects/fixed-array.h @@ -7,7 +7,6 @@ #include "src/maybe-handles.h" #include "src/objects/instance-type.h" -#include "src/objects/slots.h" #include "src/objects/smi.h" #include "torque-generated/class-definitions-from-dsl.h" diff --git a/deps/v8/src/objects/hash-table.h b/deps/v8/src/objects/hash-table.h index 5d5f4e0dd1c86d..15ad1d8538afbf 100644 --- a/deps/v8/src/objects/hash-table.h +++ b/deps/v8/src/objects/hash-table.h @@ -345,6 +345,7 @@ class EphemeronHashTable protected: friend class MarkCompactCollector; + friend class ScavengerCollector; OBJECT_CONSTRUCTORS( EphemeronHashTable, diff --git a/deps/v8/src/objects/maybe-object.h b/deps/v8/src/objects/maybe-object.h index c40ae0a5aadc37..e62099b2d5b6e1 100644 --- a/deps/v8/src/objects/maybe-object.h +++ b/deps/v8/src/objects/maybe-object.h @@ -9,7 +9,6 @@ #include "include/v8.h" #include "src/globals.h" #include "src/objects.h" -#include "src/objects/slots.h" #include "src/objects/smi.h" namespace v8 { diff --git a/deps/v8/src/objects/ordered-hash-table-inl.h b/deps/v8/src/objects/ordered-hash-table-inl.h index 95ddf061329a45..5e2dd6a9fe34bd 100644 --- a/deps/v8/src/objects/ordered-hash-table-inl.h +++ b/deps/v8/src/objects/ordered-hash-table-inl.h @@ -9,7 +9,9 @@ #include "src/heap/heap.h" #include "src/objects-inl.h" +#include "src/objects/compressed-slots.h" #include "src/objects/fixed-array-inl.h" +#include "src/objects/slots.h" // Has to be the last include (doesn't have include guards): #include "src/objects/object-macros.h" @@ -47,6 +49,22 @@ template SmallOrderedHashTable::SmallOrderedHashTable(Address ptr) : HeapObject(ptr) {} +template +Object SmallOrderedHashTable::KeyAt(int entry) const { + DCHECK_LT(entry, Capacity()); + Offset entry_offset = GetDataEntryOffset(entry, Derived::kKeyIndex); + return READ_FIELD(*this, entry_offset); +} + +template +Object SmallOrderedHashTable::GetDataEntry(int entry, + int relative_index) { + DCHECK_LT(entry, Capacity()); + DCHECK_LE(static_cast(relative_index), Derived::kEntrySize); + Offset entry_offset = GetDataEntryOffset(entry, relative_index); + return READ_FIELD(*this, entry_offset); +} + OBJECT_CONSTRUCTORS_IMPL(SmallOrderedHashSet, SmallOrderedHashTable) OBJECT_CONSTRUCTORS_IMPL(SmallOrderedHashMap, diff --git a/deps/v8/src/objects/ordered-hash-table.h b/deps/v8/src/objects/ordered-hash-table.h index 1bdab1a73e3bfc..48300fb7ba4d9f 100644 --- a/deps/v8/src/objects/ordered-hash-table.h +++ b/deps/v8/src/objects/ordered-hash-table.h @@ -403,11 +403,7 @@ class SmallOrderedHashTable : public HeapObject { int NumberOfBuckets() const { return getByte(NumberOfBucketsOffset(), 0); } - Object KeyAt(int entry) const { - DCHECK_LT(entry, Capacity()); - Offset entry_offset = GetDataEntryOffset(entry, Derived::kKeyIndex); - return READ_FIELD(*this, entry_offset); - } + V8_INLINE Object KeyAt(int entry) const; DECL_VERIFIER(SmallOrderedHashTable) @@ -487,12 +483,7 @@ class SmallOrderedHashTable : public HeapObject { return getByte(GetChainTableOffset(), entry); } - Object GetDataEntry(int entry, int relative_index) { - DCHECK_LT(entry, Capacity()); - DCHECK_LE(static_cast(relative_index), Derived::kEntrySize); - Offset entry_offset = GetDataEntryOffset(entry, relative_index); - return READ_FIELD(*this, entry_offset); - } + V8_INLINE Object GetDataEntry(int entry, int relative_index); int HashToBucket(int hash) const { return hash & (NumberOfBuckets() - 1); } diff --git a/deps/v8/src/objects/shared-function-info.h b/deps/v8/src/objects/shared-function-info.h index bf382fc4f8cb9f..b115866e24d116 100644 --- a/deps/v8/src/objects/shared-function-info.h +++ b/deps/v8/src/objects/shared-function-info.h @@ -9,7 +9,9 @@ #include "src/function-kind.h" #include "src/objects.h" #include "src/objects/builtin-function-id.h" +#include "src/objects/compressed-slots.h" #include "src/objects/script.h" +#include "src/objects/slots.h" #include "src/objects/smi.h" #include "src/objects/struct.h" #include "torque-generated/class-definitions-from-dsl.h" diff --git a/deps/v8/src/objects/slots-atomic-inl.h b/deps/v8/src/objects/slots-atomic-inl.h index c74875d2d921d3..0ef1232eec9c83 100644 --- a/deps/v8/src/objects/slots-atomic-inl.h +++ b/deps/v8/src/objects/slots-atomic-inl.h @@ -6,6 +6,7 @@ #define V8_OBJECTS_SLOTS_ATOMIC_INL_H_ #include "src/base/atomic-utils.h" +#include "src/objects/compressed-slots.h" #include "src/objects/slots.h" namespace v8 { diff --git a/deps/v8/src/objects/slots-inl.h b/deps/v8/src/objects/slots-inl.h index f0baf686e35eca..e0a42fbd91e120 100644 --- a/deps/v8/src/objects/slots-inl.h +++ b/deps/v8/src/objects/slots-inl.h @@ -12,10 +12,7 @@ #include "src/objects.h" #include "src/objects/heap-object-inl.h" #include "src/objects/maybe-object.h" - -#ifdef V8_COMPRESS_POINTERS #include "src/ptr-compr-inl.h" -#endif namespace v8 { namespace internal { diff --git a/deps/v8/src/ptr-compr-inl.h b/deps/v8/src/ptr-compr-inl.h index ac234b02814e15..1a56147c15fa94 100644 --- a/deps/v8/src/ptr-compr-inl.h +++ b/deps/v8/src/ptr-compr-inl.h @@ -7,7 +7,7 @@ #if V8_TARGET_ARCH_64_BIT -#include "src/objects/heap-object-inl.h" +#include "include/v8-internal.h" #include "src/ptr-compr.h" namespace v8 { @@ -29,176 +29,34 @@ V8_INLINE Address GetRootFromOnHeapAddress(Address addr) { // preserving both weak- and smi- tags. V8_INLINE Address DecompressTaggedPointer(Address on_heap_addr, Tagged_t raw_value) { - int32_t value = static_cast(raw_value); + // Current compression scheme requires |raw_value| to be sign-extended + // from int32_t to intptr_t. + intptr_t value = static_cast(static_cast(raw_value)); Address root = GetRootFromOnHeapAddress(on_heap_addr); - // Current compression scheme requires value to be sign-extended to inptr_t - // before adding the |root|. - return root + static_cast
(static_cast(value)); + return root + static_cast
(value); } // Decompresses any tagged value, preserving both weak- and smi- tags. V8_INLINE Address DecompressTaggedAny(Address on_heap_addr, Tagged_t raw_value) { - int32_t value = static_cast(raw_value); + // Current compression scheme requires |raw_value| to be sign-extended + // from int32_t to intptr_t. + intptr_t value = static_cast(static_cast(raw_value)); // |root_mask| is 0 if the |value| was a smi or -1 otherwise. - Address root_mask = -static_cast
(value & kSmiTagMask); + Address root_mask = static_cast
(-(value & kSmiTagMask)); Address root_or_zero = root_mask & GetRootFromOnHeapAddress(on_heap_addr); - // Current compression scheme requires value to be sign-extended to inptr_t - // before adding the |root_or_zero|. - return root_or_zero + static_cast
(static_cast(value)); + return root_or_zero + static_cast
(value); } +#ifdef V8_COMPRESS_POINTERS + STATIC_ASSERT(kPtrComprHeapReservationSize == Internals::kPtrComprHeapReservationSize); STATIC_ASSERT(kPtrComprIsolateRootBias == Internals::kPtrComprIsolateRootBias); STATIC_ASSERT(kPtrComprIsolateRootAlignment == Internals::kPtrComprIsolateRootAlignment); -// -// CompressedObjectSlot implementation. -// - -CompressedObjectSlot::CompressedObjectSlot(Object* object) - : SlotBase(reinterpret_cast
(&object->ptr_)) {} - -Object CompressedObjectSlot::operator*() const { - Tagged_t value = *location(); - return Object(DecompressTaggedAny(address(), value)); -} - -void CompressedObjectSlot::store(Object value) const { - *location() = CompressTagged(value->ptr()); -} - -Object CompressedObjectSlot::Acquire_Load() const { - AtomicTagged_t value = AsAtomicTagged::Acquire_Load(location()); - return Object(DecompressTaggedAny(address(), value)); -} - -Object CompressedObjectSlot::Relaxed_Load() const { - AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location()); - return Object(DecompressTaggedAny(address(), value)); -} - -void CompressedObjectSlot::Relaxed_Store(Object value) const { - Tagged_t ptr = CompressTagged(value->ptr()); - AsAtomicTagged::Relaxed_Store(location(), ptr); -} - -void CompressedObjectSlot::Release_Store(Object value) const { - Tagged_t ptr = CompressTagged(value->ptr()); - AsAtomicTagged::Release_Store(location(), ptr); -} - -Object CompressedObjectSlot::Release_CompareAndSwap(Object old, - Object target) const { - Tagged_t old_ptr = CompressTagged(old->ptr()); - Tagged_t target_ptr = CompressTagged(target->ptr()); - Tagged_t result = - AsAtomicTagged::Release_CompareAndSwap(location(), old_ptr, target_ptr); - return Object(DecompressTaggedAny(address(), result)); -} - -// -// CompressedMapWordSlot implementation. -// - -bool CompressedMapWordSlot::contains_value(Address raw_value) const { - AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location()); - return static_cast(value) == - static_cast(static_cast(raw_value)); -} - -Object CompressedMapWordSlot::operator*() const { - Tagged_t value = *location(); - return Object(DecompressTaggedPointer(address(), value)); -} - -void CompressedMapWordSlot::store(Object value) const { - *location() = CompressTagged(value.ptr()); -} - -Object CompressedMapWordSlot::Relaxed_Load() const { - AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location()); - return Object(DecompressTaggedPointer(address(), value)); -} - -void CompressedMapWordSlot::Relaxed_Store(Object value) const { - Tagged_t ptr = CompressTagged(value.ptr()); - AsAtomicTagged::Relaxed_Store(location(), ptr); -} - -Object CompressedMapWordSlot::Acquire_Load() const { - AtomicTagged_t value = AsAtomicTagged::Acquire_Load(location()); - return Object(DecompressTaggedPointer(address(), value)); -} - -void CompressedMapWordSlot::Release_Store(Object value) const { - Tagged_t ptr = CompressTagged(value->ptr()); - AsAtomicTagged::Release_Store(location(), ptr); -} - -Object CompressedMapWordSlot::Release_CompareAndSwap(Object old, - Object target) const { - Tagged_t old_ptr = CompressTagged(old->ptr()); - Tagged_t target_ptr = CompressTagged(target->ptr()); - Tagged_t result = - AsAtomicTagged::Release_CompareAndSwap(location(), old_ptr, target_ptr); - return Object(DecompressTaggedPointer(address(), result)); -} - -// -// CompressedMaybeObjectSlot implementation. -// - -MaybeObject CompressedMaybeObjectSlot::operator*() const { - Tagged_t value = *location(); - return MaybeObject(DecompressTaggedAny(address(), value)); -} - -void CompressedMaybeObjectSlot::store(MaybeObject value) const { - *location() = CompressTagged(value->ptr()); -} - -MaybeObject CompressedMaybeObjectSlot::Relaxed_Load() const { - AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location()); - return MaybeObject(DecompressTaggedAny(address(), value)); -} - -void CompressedMaybeObjectSlot::Relaxed_Store(MaybeObject value) const { - Tagged_t ptr = CompressTagged(value->ptr()); - AsAtomicTagged::Relaxed_Store(location(), ptr); -} - -void CompressedMaybeObjectSlot::Release_CompareAndSwap( - MaybeObject old, MaybeObject target) const { - Tagged_t old_ptr = CompressTagged(old->ptr()); - Tagged_t target_ptr = CompressTagged(target->ptr()); - AsAtomicTagged::Release_CompareAndSwap(location(), old_ptr, target_ptr); -} - -// -// CompressedHeapObjectSlot implementation. -// - -HeapObjectReference CompressedHeapObjectSlot::operator*() const { - Tagged_t value = *location(); - return HeapObjectReference(DecompressTaggedPointer(address(), value)); -} - -void CompressedHeapObjectSlot::store(HeapObjectReference value) const { - *location() = CompressTagged(value.ptr()); -} - -HeapObject CompressedHeapObjectSlot::ToHeapObject() const { - Tagged_t value = *location(); - DCHECK_EQ(value & kHeapObjectTagMask, kHeapObjectTag); - return HeapObject::cast(Object(DecompressTaggedPointer(address(), value))); -} - -void CompressedHeapObjectSlot::StoreHeapObject(HeapObject value) const { - *location() = CompressTagged(value->ptr()); -} +#endif // V8_COMPRESS_POINTERS } // namespace internal } // namespace v8 diff --git a/deps/v8/src/ptr-compr.h b/deps/v8/src/ptr-compr.h index 00d410e1ce3aaa..3ae54e94cf7b43 100644 --- a/deps/v8/src/ptr-compr.h +++ b/deps/v8/src/ptr-compr.h @@ -8,7 +8,6 @@ #if V8_TARGET_ARCH_64_BIT #include "src/globals.h" -#include "src/objects/slots.h" namespace v8 { namespace internal { @@ -18,127 +17,6 @@ constexpr size_t kPtrComprHeapReservationSize = size_t{4} * GB; constexpr size_t kPtrComprIsolateRootBias = kPtrComprHeapReservationSize / 2; constexpr size_t kPtrComprIsolateRootAlignment = size_t{4} * GB; -// A CompressedObjectSlot instance describes a kTaggedSize-sized field ("slot") -// holding a compressed tagged pointer (smi or heap object). -// Its address() is the address of the slot. -// The slot's contents can be read and written using operator* and store(). -class CompressedObjectSlot : public SlotBase { - public: - using TObject = Object; - using THeapObjectSlot = CompressedHeapObjectSlot; - - static constexpr bool kCanBeWeak = false; - - CompressedObjectSlot() : SlotBase(kNullAddress) {} - explicit CompressedObjectSlot(Address ptr) : SlotBase(ptr) {} - explicit CompressedObjectSlot(Address* ptr) - : SlotBase(reinterpret_cast
(ptr)) {} - inline explicit CompressedObjectSlot(Object* object); - explicit CompressedObjectSlot(Object const* const* ptr) - : SlotBase(reinterpret_cast
(ptr)) {} - template - explicit CompressedObjectSlot(SlotBase slot) - : SlotBase(slot.address()) {} - - inline Object operator*() const; - inline void store(Object value) const; - - inline Object Acquire_Load() const; - inline Object Relaxed_Load() const; - inline void Relaxed_Store(Object value) const; - inline void Release_Store(Object value) const; - inline Object Release_CompareAndSwap(Object old, Object target) const; -}; - -// A CompressedMapWordSlot instance describes a kTaggedSize-sized map-word field -// ("slot") of heap objects holding a compressed tagged pointer or a Smi -// representing forwaring pointer value. -// This slot kind is similar to CompressedObjectSlot but decompression of -// forwarding pointer is different. -// Its address() is the address of the slot. -// The slot's contents can be read and written using operator* and store(). -class CompressedMapWordSlot : public SlotBase { - public: - using TObject = Object; - - static constexpr bool kCanBeWeak = false; - - CompressedMapWordSlot() : SlotBase(kNullAddress) {} - explicit CompressedMapWordSlot(Address ptr) : SlotBase(ptr) {} - - // Compares memory representation of a value stored in the slot with given - // raw value without decompression. - inline bool contains_value(Address raw_value) const; - - inline Object operator*() const; - inline void store(Object value) const; - - inline Object Relaxed_Load() const; - inline void Relaxed_Store(Object value) const; - - inline Object Acquire_Load() const; - inline void Release_Store(Object value) const; - inline Object Release_CompareAndSwap(Object old, Object target) const; -}; - -// A CompressedMaybeObjectSlot instance describes a kTaggedSize-sized field -// ("slot") holding a possibly-weak compressed tagged pointer -// (think: MaybeObject). -// Its address() is the address of the slot. -// The slot's contents can be read and written using operator* and store(). -class CompressedMaybeObjectSlot - : public SlotBase { - public: - using TObject = MaybeObject; - using THeapObjectSlot = CompressedHeapObjectSlot; - - static constexpr bool kCanBeWeak = true; - - CompressedMaybeObjectSlot() : SlotBase(kNullAddress) {} - explicit CompressedMaybeObjectSlot(Address ptr) : SlotBase(ptr) {} - explicit CompressedMaybeObjectSlot(Object* ptr) - : SlotBase(reinterpret_cast
(ptr)) {} - explicit CompressedMaybeObjectSlot(MaybeObject* ptr) - : SlotBase(reinterpret_cast
(ptr)) {} - template - explicit CompressedMaybeObjectSlot( - SlotBase slot) - : SlotBase(slot.address()) {} - - inline MaybeObject operator*() const; - inline void store(MaybeObject value) const; - - inline MaybeObject Relaxed_Load() const; - inline void Relaxed_Store(MaybeObject value) const; - inline void Release_CompareAndSwap(MaybeObject old, MaybeObject target) const; -}; - -// A CompressedHeapObjectSlot instance describes a kTaggedSize-sized field -// ("slot") holding a weak or strong compressed pointer to a heap object (think: -// HeapObjectReference). -// Its address() is the address of the slot. -// The slot's contents can be read and written using operator* and store(). -// In case it is known that that slot contains a strong heap object pointer, -// ToHeapObject() can be used to retrieve that heap object. -class CompressedHeapObjectSlot - : public SlotBase { - public: - CompressedHeapObjectSlot() : SlotBase(kNullAddress) {} - explicit CompressedHeapObjectSlot(Address ptr) : SlotBase(ptr) {} - explicit CompressedHeapObjectSlot(Object* ptr) - : SlotBase(reinterpret_cast
(ptr)) {} - template - explicit CompressedHeapObjectSlot(SlotBase slot) - : SlotBase(slot.address()) {} - - inline HeapObjectReference operator*() const; - inline void store(HeapObjectReference value) const; - - inline HeapObject ToHeapObject() const; - - inline void StoreHeapObject(HeapObject value) const; -}; - } // namespace internal } // namespace v8 diff --git a/deps/v8/src/string-case.cc b/deps/v8/src/string-case.cc index e9004a37eeec53..d3def4110c689f 100644 --- a/deps/v8/src/string-case.cc +++ b/deps/v8/src/string-case.cc @@ -17,6 +17,10 @@ namespace internal { // string data depends on kTaggedSize so we define word_t via Tagged_t. using word_t = std::make_unsigned::type; +const word_t kWordTAllBitsSet = std::numeric_limits::max(); +const word_t kOneInEveryByte = kWordTAllBitsSet / 0xFF; +const word_t kAsciiMask = kOneInEveryByte << 7; + #ifdef DEBUG bool CheckFastAsciiConvert(char* dst, const char* src, int length, bool changed, bool is_to_lower) { @@ -36,9 +40,6 @@ bool CheckFastAsciiConvert(char* dst, const char* src, int length, bool changed, } #endif -const word_t kOneInEveryByte = static_cast(kUintptrAllBitsSet) / 0xFF; -const word_t kAsciiMask = kOneInEveryByte << 7; - // Given a word and two range boundaries returns a word with high bit // set in every byte iff the corresponding input byte was strictly in // the range (m, n). All the other bits in the result are cleared. diff --git a/deps/v8/src/visitors.h b/deps/v8/src/visitors.h index 28f925cbac18a0..bc9e9fade09e60 100644 --- a/deps/v8/src/visitors.h +++ b/deps/v8/src/visitors.h @@ -7,6 +7,7 @@ #include "src/globals.h" #include "src/objects/code.h" +#include "src/objects/compressed-slots.h" #include "src/objects/foreign.h" #include "src/objects/slots.h" diff --git a/deps/v8/src/wasm/baseline/arm64/liftoff-assembler-arm64.h b/deps/v8/src/wasm/baseline/arm64/liftoff-assembler-arm64.h index 50e8e0db94357f..0c093f2dcd165a 100644 --- a/deps/v8/src/wasm/baseline/arm64/liftoff-assembler-arm64.h +++ b/deps/v8/src/wasm/baseline/arm64/liftoff-assembler-arm64.h @@ -206,9 +206,10 @@ void LiftoffAssembler::LoadTaggedPointer(Register dst, Register src_addr, Register offset_reg, uint32_t offset_imm, LiftoffRegList pinned) { - STATIC_ASSERT(kTaggedSize == kInt64Size); - Load(LiftoffRegister(dst), src_addr, offset_reg, offset_imm, - LoadType::kI64Load, pinned); + UseScratchRegisterScope temps(this); + MemOperand src_op = + liftoff::GetMemOp(this, &temps, src_addr, offset_reg, offset_imm); + LoadTaggedPointerField(dst, src_op); } void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr, diff --git a/deps/v8/test/cctest/test-code-stub-assembler.cc b/deps/v8/test/cctest/test-code-stub-assembler.cc index e7f592d1c55815..732d20fe669fee 100644 --- a/deps/v8/test/cctest/test-code-stub-assembler.cc +++ b/deps/v8/test/cctest/test-code-stub-assembler.cc @@ -255,7 +255,7 @@ TEST(IsValidPositiveSmi) { typedef std::numeric_limits int32_limits; IsValidPositiveSmiCase(isolate, int32_limits::max()); IsValidPositiveSmiCase(isolate, int32_limits::min()); -#ifdef V8_TARGET_ARCH_64_BIT +#if V8_TARGET_ARCH_64_BIT IsValidPositiveSmiCase(isolate, static_cast(int32_limits::max()) + 1); IsValidPositiveSmiCase(isolate,