From b1015e0de80bbf7ba02b1234cdf8f9a9026a27fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Sat, 16 Mar 2019 22:58:48 +0100 Subject: [PATCH] deps: V8: cherry-pick 6 commits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cherry-pick ad49f12. Original commit message: [cleanup] Move Compressed[XXX]Slot definitions to separate header ... and fix header includes to please the respective bot. Drive-by-fix: decompression implementation is now MSVC friendly. Bug: v8:7703, v8:8834 Change-Id: Iaf589138e5bafb32b0d9feab5cf074b71f241a3c Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1505579 Commit-Queue: Igor Sheludko Reviewed-by: Ulan Degenbaev Cr-Commit-Position: refs/heads/master@{#60074} Refs: https://github.com/v8/v8/commit/ad49f12908644fa1dc7e5aa28839a85872084f8c Cherry-pick 14f07a8. Original commit message: [ptr-compr] Define kTaggedPayloadOffset correctly on Big Endian smi size is sill 8 bytes when V8_COMPRESS_POINTERS is undefined. Bug: v8:7703 Change-Id: I0d1e757e42e8b1e6b10960420135245e24553175 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1508572 Commit-Queue: Junliang Yan Auto-Submit: Junliang Yan Reviewed-by: Igor Sheludko Cr-Commit-Position: refs/heads/master@{#60097} Refs: https://github.com/v8/v8/commit/14f07a8b30dd28bd6508924fae01e0c2d1892aad Cherry-pick 676014b. Original commit message: [ptr-compr] Fix MSVC build ... which complained about truncating uintptr_t constant to uint32_t. Bug: v8:7703 Change-Id: I6fae2bf1e5de79e6131479b84a8d8aa5b9de909f Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1508672 Reviewed-by: Ulan Degenbaev Commit-Queue: Igor Sheludko Cr-Commit-Position: refs/heads/master@{#60100} Refs: https://github.com/v8/v8/commit/676014b36ffb28f9d25e5d232547deb5735baa44 Cherry-pick 4e6a1a7. Original commit message: [heap] Clean-up some weak map entries in scavenger This change enables clean-up of weak map entries in the scavenger of the weak map is in the young generation. With this change, the scavenger treats keys in ephemerons as weak instead of strong, but does not implement full ephemeron semantics: Values are treated always as strong, independently of whether the key is live or not. This approach ensures that no value is cleaned up accidentally. After scavenging, all entries with dead keys are removed from weak maps. After that, some values that are not referenced anywhere anymore might still be in the heap, and those can be cleaned up in the next scavenge. What the scavenger does, amounts to one iteration of the fixed-point algorithm required to implement ephemeron semantics. We hope that this is a reasonable trade-off between time spent tracing and cleaned-up entries. This change does not affect weak maps that reside in old space. Bug: v8:8557 Change-Id: Ic5618b3b863ad8c314c87449571150e756fecbf0 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1467182 Commit-Queue: Sigurd Schneider Reviewed-by: Ulan Degenbaev Cr-Commit-Position: refs/heads/master@{#60101} Refs: https://github.com/v8/v8/commit/4e6a1a75cd75916b45956071e581df6121bceaa8 Cherry-pick afbfd75. Original commit message: [ptr-compr] Fix ptr-compr broken by 4e6a1a75 (https://chromium-review.googlesource.com/c/v8/v8/+/1467182) Bug: v8:7703 Change-Id: Ia6b74b985735af67bde56b30e4a709247eb591be Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1508674 Commit-Queue: Igor Sheludko Commit-Queue: Ulan Degenbaev Reviewed-by: Ulan Degenbaev Cr-Commit-Position: refs/heads/master@{#60102} Refs: https://github.com/v8/v8/commit/afbfd7563d88b90b095b454344f91de6138cbbf3 Cherry-pick f792eb8. Original commit message: [ptr-compr][arm64] Update pointer compression arm64's implementation Since kTaggedSize got shrinked and we are actually compressing the pointers (as oppposed to zeroing their upper bits), we need to update the arm64 codebase to accommodate this change. Cq-Include-Trybots: luci.v8.try:v8_linux64_arm64_pointer_compression_rel_ng Bug: v8:7703 Change-Id: I890f3ab8c046f47232e80f85830f9ae8f4dbced4 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1499498 Commit-Queue: Santiago Aboy Solanes Reviewed-by: Igor Sheludko Reviewed-by: Ross McIlroy Reviewed-by: Clemens Hammacher Cr-Commit-Position: refs/heads/master@{#60172} Refs: https://github.com/v8/v8/commit/f792eb83a6501d44d4ef51b11894ce2ba9dc8f91 PR-URL: https://github.com/nodejs/node/pull/26685 Reviewed-By: Anna Henningsen Reviewed-By: Michaƫl Zasso Reviewed-By: Refael Ackermann --- common.gypi | 2 +- deps/v8/BUILD.gn | 2 + deps/v8/src/arm64/macro-assembler-arm64-inl.h | 4 + deps/v8/src/arm64/macro-assembler-arm64.cc | 20 +-- deps/v8/src/base/macros.h | 2 +- deps/v8/src/bootstrapper.h | 1 - deps/v8/src/builtins/arm64/builtins-arm64.cc | 2 +- deps/v8/src/heap/heap-write-barrier-inl.h | 1 + deps/v8/src/heap/heap.h | 14 ++ deps/v8/src/heap/incremental-marking.cc | 16 -- deps/v8/src/heap/scavenger-inl.h | 15 ++ deps/v8/src/heap/scavenger.cc | 66 ++++++- deps/v8/src/heap/scavenger.h | 13 +- deps/v8/src/heap/slot-set.h | 5 +- deps/v8/src/heap/worklist.h | 2 + deps/v8/src/isolate.cc | 2 +- deps/v8/src/objects-body-descriptors-inl.h | 1 - deps/v8/src/objects.h | 4 - deps/v8/src/objects/compressed-slots-inl.h | 169 ++++++++++++++++++ deps/v8/src/objects/compressed-slots.h | 141 +++++++++++++++ deps/v8/src/objects/embedder-data-array-inl.h | 1 - deps/v8/src/objects/embedder-data-slot.h | 6 +- deps/v8/src/objects/fixed-array-inl.h | 1 + deps/v8/src/objects/fixed-array.h | 1 - deps/v8/src/objects/hash-table.h | 1 + deps/v8/src/objects/maybe-object.h | 1 - deps/v8/src/objects/ordered-hash-table-inl.h | 18 ++ deps/v8/src/objects/ordered-hash-table.h | 13 +- deps/v8/src/objects/shared-function-info.h | 2 + deps/v8/src/objects/slots-atomic-inl.h | 1 + deps/v8/src/objects/slots-inl.h | 3 - deps/v8/src/ptr-compr-inl.h | 168 ++--------------- deps/v8/src/ptr-compr.h | 122 ------------- deps/v8/src/string-case.cc | 7 +- deps/v8/src/visitors.h | 1 + .../baseline/arm64/liftoff-assembler-arm64.h | 7 +- .../test/cctest/test-code-stub-assembler.cc | 2 +- 37 files changed, 478 insertions(+), 359 deletions(-) create mode 100644 deps/v8/src/objects/compressed-slots-inl.h create mode 100644 deps/v8/src/objects/compressed-slots.h 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,