From 795108a63d14aedfcc1b320b0754c464ea794e49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Tue, 12 Oct 2021 08:49:00 +0200 Subject: [PATCH] deps: V8: make V8 9.5 ABI-compatible with 9.6 Cherry-pick ABI-breaking changes that happened since 9.5 was branched: [api] Remove deprecated HostImportModuleDynamicallyCallback Refs: https://github.com/v8/v8/commit/ab836859d964d03ec43de9e7d0096c4ebf6ab64c [zone] Provide a way to configure allocator for zone backings Refs: https://github.com/v8/v8/commit/e262e1cb4a0f9ab0051eb981a01dc1e66c0b4125 [isolate-data] Consistent field names Needed for the next commit. Refs: https://github.com/v8/v8/commit/d09fc5403aaa7ce18d01d79da067ebc2408d18ed [isolate-data] Split builtin tables into tiers Refs: https://github.com/v8/v8/commit/06af754cea8006e0a802655250c129dc8e9cdce0 [mips][loong64][isolate-data] Split builtin tables into tiers Refs: https://github.com/v8/v8/commit/1fd55617e15b07b0b939d795db16dd07a7656e85 [riscv64] Replace builtin_entry_slot_offset with BuiltinEntrySlotOffset Refs: https://github.com/v8/v8/commit/b66d5f023315160623b17d8ee686f26a82ae374b ppc/s390: [isolate-data] Split builtin tables into tiers Refs: https://github.com/v8/v8/commit/dc88bdf35ea708bf6ff7ab7816d2fc554ae902a1 PR-URL: https://github.com/nodejs/node/pull/40422 Reviewed-By: Antoine du Hamel Reviewed-By: Beth Griggs --- common.gypi | 2 +- deps/v8/include/v8-callbacks.h | 25 -- deps/v8/include/v8-internal.h | 23 +- deps/v8/include/v8-isolate.h | 10 - deps/v8/include/v8-platform.h | 20 ++ deps/v8/src/api/api.cc | 6 - deps/v8/src/builtins/builtins-definitions.h | 71 +++-- deps/v8/src/builtins/builtins.cc | 44 +-- deps/v8/src/builtins/builtins.h | 15 +- deps/v8/src/codegen/arm/assembler-arm.h | 8 +- .../v8/src/codegen/arm/macro-assembler-arm.cc | 19 +- .../codegen/arm64/macro-assembler-arm64.cc | 2 +- .../src/codegen/ia32/macro-assembler-ia32.cc | 3 +- .../loong64/macro-assembler-loong64.cc | 6 +- .../src/codegen/mips/macro-assembler-mips.cc | 4 +- .../codegen/mips64/macro-assembler-mips64.cc | 4 +- .../v8/src/codegen/ppc/macro-assembler-ppc.cc | 42 +-- deps/v8/src/codegen/ppc/macro-assembler-ppc.h | 1 + .../riscv64/macro-assembler-riscv64.cc | 4 +- .../src/codegen/s390/macro-assembler-s390.cc | 28 +- .../src/codegen/s390/macro-assembler-s390.h | 1 + deps/v8/src/codegen/turbo-assembler.cc | 2 +- .../v8/src/codegen/x64/macro-assembler-x64.cc | 3 +- deps/v8/src/compiler/wasm-compiler.cc | 2 +- .../v8/src/deoptimizer/arm/deoptimizer-arm.cc | 13 + .../v8/src/deoptimizer/ppc/deoptimizer-ppc.cc | 17 +- .../riscv64/deoptimizer-riscv64.cc | 6 +- .../src/deoptimizer/s390/deoptimizer-s390.cc | 13 + .../v8/src/deoptimizer/x64/deoptimizer-x64.cc | 19 +- deps/v8/src/diagnostics/disassembler.cc | 23 +- deps/v8/src/execution/frames.cc | 3 +- deps/v8/src/execution/isolate-data.h | 272 ++++++++---------- deps/v8/src/execution/isolate.cc | 62 ++-- deps/v8/src/execution/isolate.h | 18 +- deps/v8/src/handles/handles.cc | 2 +- deps/v8/src/heap/heap.cc | 24 +- deps/v8/src/heap/heap.h | 1 + deps/v8/src/utils/allocation.cc | 4 +- deps/v8/src/utils/allocation.h | 4 +- deps/v8/src/utils/utils.h | 3 +- deps/v8/src/zone/accounting-allocator.cc | 10 +- deps/v8/src/zone/accounting-allocator.h | 4 + 42 files changed, 458 insertions(+), 385 deletions(-) diff --git a/common.gypi b/common.gypi index 505cacb938e664..d4a34f0e0c277e 100644 --- a/common.gypi +++ b/common.gypi @@ -36,7 +36,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.11', + 'v8_embedder_string': '-node.12', ##### V8 defaults for Node.js ##### diff --git a/deps/v8/include/v8-callbacks.h b/deps/v8/include/v8-callbacks.h index 596fe3de4eb90f..f424a24d8bdfff 100644 --- a/deps/v8/include/v8-callbacks.h +++ b/deps/v8/include/v8-callbacks.h @@ -210,31 +210,6 @@ using CreateHistogramCallback = void* (*)(const char* name, int min, int max, using AddHistogramSampleCallback = void (*)(void* histogram, int sample); -/** - * HostImportModuleDynamicallyCallback is called when we require the - * embedder to load a module. This is used as part of the dynamic - * import syntax. - * - * The referrer contains metadata about the script/module that calls - * import. - * - * The specifier is the name of the module that should be imported. - * - * The embedder must compile, instantiate, evaluate the Module, and - * obtain its namespace object. - * - * The Promise returned from this function is forwarded to userland - * JavaScript. The embedder must resolve this promise with the module - * namespace object. In case of an exception, the embedder must reject - * this promise with the exception. If the promise creation itself - * fails (e.g. due to stack overflow), the embedder must propagate - * that exception by returning an empty MaybeLocal. - */ -using HostImportModuleDynamicallyCallback = - MaybeLocal (*)(Local context, - Local referrer, - Local specifier); - // --- Exceptions --- using FatalErrorCallback = void (*)(const char* location, const char* message); diff --git a/deps/v8/include/v8-internal.h b/deps/v8/include/v8-internal.h index 6516a16219fc09..4a84fc066a848b 100644 --- a/deps/v8/include/v8-internal.h +++ b/deps/v8/include/v8-internal.h @@ -224,23 +224,30 @@ class Internals { static const int kExternalOneByteRepresentationTag = 0x0a; static const uint32_t kNumIsolateDataSlots = 4; + static const int kStackGuardSize = 7 * kApiSystemPointerSize; + static const int kBuiltinTier0EntryTableSize = 13 * kApiSystemPointerSize; + static const int kBuiltinTier0TableSize = 13 * kApiSystemPointerSize; // IsolateData layout guarantees. - static const int kIsolateEmbedderDataOffset = 0; + static const int kIsolateCageBaseOffset = 0; + static const int kIsolateStackGuardOffset = + kIsolateCageBaseOffset + kApiSystemPointerSize; + static const int kBuiltinTier0EntryTableOffset = + kIsolateStackGuardOffset + kStackGuardSize; + static const int kBuiltinTier0TableOffset = + kBuiltinTier0EntryTableOffset + kBuiltinTier0EntryTableSize; + static const int kIsolateEmbedderDataOffset = + kBuiltinTier0TableOffset + kBuiltinTier0TableSize; static const int kIsolateFastCCallCallerFpOffset = - kNumIsolateDataSlots * kApiSystemPointerSize; + kIsolateEmbedderDataOffset + kNumIsolateDataSlots * kApiSystemPointerSize; static const int kIsolateFastCCallCallerPcOffset = kIsolateFastCCallCallerFpOffset + kApiSystemPointerSize; static const int kIsolateFastApiCallTargetOffset = kIsolateFastCCallCallerPcOffset + kApiSystemPointerSize; - static const int kIsolateCageBaseOffset = - kIsolateFastApiCallTargetOffset + kApiSystemPointerSize; static const int kIsolateLongTaskStatsCounterOffset = - kIsolateCageBaseOffset + kApiSystemPointerSize; - static const int kIsolateStackGuardOffset = - kIsolateLongTaskStatsCounterOffset + kApiSizetSize; + kIsolateFastApiCallTargetOffset + kApiSystemPointerSize; static const int kIsolateRootsOffset = - kIsolateStackGuardOffset + 7 * kApiSystemPointerSize; + kIsolateLongTaskStatsCounterOffset + kApiSizetSize; static const int kExternalPointerTableBufferOffset = 0; static const int kExternalPointerTableLengthOffset = diff --git a/deps/v8/include/v8-isolate.h b/deps/v8/include/v8-isolate.h index c018859c020c93..dc4af456b5e76f 100644 --- a/deps/v8/include/v8-isolate.h +++ b/deps/v8/include/v8-isolate.h @@ -613,16 +613,6 @@ class V8_EXPORT Isolate { void SetAbortOnUncaughtExceptionCallback( AbortOnUncaughtExceptionCallback callback); - /** - * This specifies the callback called by the upcoming dynamic - * import() language feature to load modules. - */ - V8_DEPRECATED( - "Use the version of SetHostImportModuleDynamicallyCallback that takes a " - "HostImportModuleDynamicallyWithImportAssertionsCallback instead") - void SetHostImportModuleDynamicallyCallback( - HostImportModuleDynamicallyCallback callback); - /** * This specifies the callback called by the upcoming dynamic * import() language feature to load modules. diff --git a/deps/v8/include/v8-platform.h b/deps/v8/include/v8-platform.h index dee399fa771606..e60e1757b63941 100644 --- a/deps/v8/include/v8-platform.h +++ b/deps/v8/include/v8-platform.h @@ -516,6 +516,18 @@ class PageAllocator { virtual bool CanAllocateSharedPages() { return false; } }; +/** + * V8 Allocator used for allocating zone backings. + */ +class ZoneBackingAllocator { + public: + using MallocFn = void* (*)(size_t); + using FreeFn = void (*)(void*); + + virtual MallocFn GetMallocFn() const { return ::malloc; } + virtual FreeFn GetFreeFn() const { return ::free; } +}; + /** * V8 Platform abstraction layer. * @@ -534,6 +546,14 @@ class Platform { return nullptr; } + /** + * Allows the embedder to specify a custom allocator used for zones. + */ + virtual ZoneBackingAllocator* GetZoneBackingAllocator() { + static ZoneBackingAllocator default_allocator; + return &default_allocator; + } + /** * Enables the embedder to respond in cases where V8 can't allocate large * blocks of memory. V8 retries the failed allocation once after calling this diff --git a/deps/v8/src/api/api.cc b/deps/v8/src/api/api.cc index dedbd5db668237..81057d6e7a440e 100644 --- a/deps/v8/src/api/api.cc +++ b/deps/v8/src/api/api.cc @@ -8544,12 +8544,6 @@ void Isolate::SetAbortOnUncaughtExceptionCallback( isolate->SetAbortOnUncaughtExceptionCallback(callback); } -void Isolate::SetHostImportModuleDynamicallyCallback( - i::Isolate::DeprecatedHostImportModuleDynamicallyCallback callback) { - i::Isolate* isolate = reinterpret_cast(this); - isolate->SetHostImportModuleDynamicallyCallback(callback); -} - void Isolate::SetHostImportModuleDynamicallyCallback( HostImportModuleDynamicallyWithImportAssertionsCallback callback) { i::Isolate* isolate = reinterpret_cast(this); diff --git a/deps/v8/src/builtins/builtins-definitions.h b/deps/v8/src/builtins/builtins-definitions.h index 0c89b0e45af0dc..c63db39b044f4e 100644 --- a/deps/v8/src/builtins/builtins-definitions.h +++ b/deps/v8/src/builtins/builtins-definitions.h @@ -31,16 +31,40 @@ namespace internal { // TODO(jgruber): Remove DummyDescriptor once all ASM builtins have been // properly associated with their descriptor. -#define BUILTIN_LIST_BASE(CPP, TFJ, TFC, TFS, TFH, ASM) \ - /* GC write barrirer */ \ - TFC(RecordWriteEmitRememberedSetSaveFP, WriteBarrier) \ - TFC(RecordWriteOmitRememberedSetSaveFP, WriteBarrier) \ - TFC(RecordWriteEmitRememberedSetIgnoreFP, WriteBarrier) \ - TFC(RecordWriteOmitRememberedSetIgnoreFP, WriteBarrier) \ - TFC(EphemeronKeyBarrierSaveFP, WriteBarrier) \ - TFC(EphemeronKeyBarrierIgnoreFP, WriteBarrier) \ - \ - /* TSAN support for stores in generated code.*/ \ +// Builtins are additionally split into tiers, where the tier determines the +// distance of the builtins table from the root register within IsolateData. +// +// - Tier 0 (T0) are guaranteed to be close to the root register and can thus +// be accessed efficiently root-relative calls (so not, e.g., calls from +// generated code when short-builtin-calls is on). +// - T1 builtins have no distance guarantees. +// +// Note, this mechanism works only if the set of T0 builtins is kept as small +// as possible. Please, resist the temptation to add your builtin here unless +// there's a very good reason. +#define BUILTIN_LIST_BASE_TIER0(CPP, TFJ, TFC, TFS, TFH, ASM) \ + /* Deoptimization entries. */ \ + ASM(DeoptimizationEntry_Eager, DeoptimizationEntry) \ + ASM(DeoptimizationEntry_Soft, DeoptimizationEntry) \ + ASM(DeoptimizationEntry_Bailout, DeoptimizationEntry) \ + ASM(DeoptimizationEntry_Lazy, DeoptimizationEntry) \ + ASM(DynamicCheckMapsTrampoline, DynamicCheckMaps) \ + ASM(DynamicCheckMapsWithFeedbackVectorTrampoline, \ + DynamicCheckMapsWithFeedbackVector) \ + \ + /* GC write barrier. */ \ + TFC(RecordWriteEmitRememberedSetSaveFP, WriteBarrier) \ + TFC(RecordWriteOmitRememberedSetSaveFP, WriteBarrier) \ + TFC(RecordWriteEmitRememberedSetIgnoreFP, WriteBarrier) \ + TFC(RecordWriteOmitRememberedSetIgnoreFP, WriteBarrier) \ + TFC(EphemeronKeyBarrierSaveFP, WriteBarrier) \ + TFC(EphemeronKeyBarrierIgnoreFP, WriteBarrier) \ + \ + /* Adaptor for CPP builtins. */ \ + TFC(AdaptorWithBuiltinExitFrame, CppBuiltinAdaptor) + +#define BUILTIN_LIST_BASE_TIER1(CPP, TFJ, TFC, TFS, TFH, ASM) \ + /* TSAN support for stores in generated code. */ \ IF_TSAN(TFC, TSANRelaxedStore8IgnoreFP, TSANStore) \ IF_TSAN(TFC, TSANRelaxedStore8SaveFP, TSANStore) \ IF_TSAN(TFC, TSANRelaxedStore16IgnoreFP, TSANStore) \ @@ -58,15 +82,12 @@ namespace internal { IF_TSAN(TFC, TSANSeqCstStore64IgnoreFP, TSANStore) \ IF_TSAN(TFC, TSANSeqCstStore64SaveFP, TSANStore) \ \ - /* TSAN support for loads in generated code.*/ \ + /* TSAN support for loads in generated code. */ \ IF_TSAN(TFC, TSANRelaxedLoad32IgnoreFP, TSANLoad) \ IF_TSAN(TFC, TSANRelaxedLoad32SaveFP, TSANLoad) \ IF_TSAN(TFC, TSANRelaxedLoad64IgnoreFP, TSANLoad) \ IF_TSAN(TFC, TSANRelaxedLoad64SaveFP, TSANLoad) \ \ - /* Adaptor for CPP builtin */ \ - TFC(AdaptorWithBuiltinExitFrame, CppBuiltinAdaptor) \ - \ /* Calls */ \ /* ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) */ \ ASM(CallFunction_ReceiverIsNullOrUndefined, CallTrampoline) \ @@ -187,10 +208,6 @@ namespace internal { TFC(CompileLazyDeoptimizedCode, JSTrampoline) \ TFC(InstantiateAsmJs, JSTrampoline) \ ASM(NotifyDeoptimized, Dummy) \ - ASM(DeoptimizationEntry_Eager, DeoptimizationEntry) \ - ASM(DeoptimizationEntry_Soft, DeoptimizationEntry) \ - ASM(DeoptimizationEntry_Bailout, DeoptimizationEntry) \ - ASM(DeoptimizationEntry_Lazy, DeoptimizationEntry) \ \ /* Trampolines called when returning from a deoptimization that expects */ \ /* to continue in a JavaScript builtin to finish the functionality of a */ \ @@ -282,10 +299,7 @@ namespace internal { TFH(HasIndexedInterceptorIC, LoadWithVector) \ \ /* Dynamic check maps */ \ - ASM(DynamicCheckMapsTrampoline, DynamicCheckMaps) \ TFC(DynamicCheckMaps, DynamicCheckMaps) \ - ASM(DynamicCheckMapsWithFeedbackVectorTrampoline, \ - DynamicCheckMapsWithFeedbackVector) \ TFC(DynamicCheckMapsWithFeedbackVector, DynamicCheckMapsWithFeedbackVector) \ \ /* Microtask helpers */ \ @@ -1032,6 +1046,10 @@ namespace internal { CPP(CallAsyncModuleFulfilled) \ CPP(CallAsyncModuleRejected) +#define BUILTIN_LIST_BASE(CPP, TFJ, TFC, TFS, TFH, ASM) \ + BUILTIN_LIST_BASE_TIER0(CPP, TFJ, TFC, TFS, TFH, ASM) \ + BUILTIN_LIST_BASE_TIER1(CPP, TFJ, TFC, TFS, TFH, ASM) + #ifdef V8_INTL_SUPPORT #define BUILTIN_LIST_INTL(CPP, TFJ, TFS) \ /* ecma402 #sec-intl.collator */ \ @@ -1218,6 +1236,17 @@ namespace internal { BUILTIN_LIST_INTL(CPP, TFJ, TFS) \ BUILTIN_LIST_BYTECODE_HANDLERS(BCH) +// See the comment on top of BUILTIN_LIST_BASE_TIER0 for an explanation of +// tiers. +#define BUILTIN_LIST_TIER0(CPP, TFJ, TFC, TFS, TFH, BCH, ASM) \ + BUILTIN_LIST_BASE_TIER0(CPP, TFJ, TFC, TFS, TFH, ASM) + +#define BUILTIN_LIST_TIER1(CPP, TFJ, TFC, TFS, TFH, BCH, ASM) \ + BUILTIN_LIST_BASE_TIER1(CPP, TFJ, TFC, TFS, TFH, ASM) \ + BUILTIN_LIST_FROM_TORQUE(CPP, TFJ, TFC, TFS, TFH, ASM) \ + BUILTIN_LIST_INTL(CPP, TFJ, TFS) \ + BUILTIN_LIST_BYTECODE_HANDLERS(BCH) + // The exception thrown in the following builtins are caught // internally and result in a promise rejection. #define BUILTIN_PROMISE_REJECTION_PREDICTION_LIST(V) \ diff --git a/deps/v8/src/builtins/builtins.cc b/deps/v8/src/builtins/builtins.cc index e2d3acef368045..c01e2dceb15974 100644 --- a/deps/v8/src/builtins/builtins.cc +++ b/deps/v8/src/builtins/builtins.cc @@ -92,7 +92,7 @@ BytecodeOffset Builtins::GetContinuationBytecodeOffset(Builtin builtin) { DCHECK(Builtins::KindOf(builtin) == TFJ || Builtins::KindOf(builtin) == TFC || Builtins::KindOf(builtin) == TFS); return BytecodeOffset(BytecodeOffset::kFirstBuiltinContinuationId + - static_cast(builtin)); + ToInt(builtin)); } Builtin Builtins::GetBuiltinFromBytecodeOffset(BytecodeOffset id) { @@ -182,7 +182,7 @@ Handle Builtins::code_handle(Builtin builtin) { // static int Builtins::GetStackParameterCount(Builtin builtin) { DCHECK(Builtins::KindOf(builtin) == TFJ); - return builtin_metadata[static_cast(builtin)].data.parameter_count; + return builtin_metadata[ToInt(builtin)].data.parameter_count; } // static @@ -224,7 +224,7 @@ bool Builtins::HasJSLinkage(Builtin builtin) { // static const char* Builtins::name(Builtin builtin) { - int index = static_cast(builtin); + int index = ToInt(builtin); DCHECK(IsBuiltinId(index)); return builtin_metadata[index].name; } @@ -262,7 +262,7 @@ void Builtins::PrintBuiltinSize() { // static Address Builtins::CppEntryOf(Builtin builtin) { DCHECK(Builtins::IsCpp(builtin)); - return builtin_metadata[static_cast(builtin)].data.cpp_entry; + return builtin_metadata[ToInt(builtin)].data.cpp_entry; } // static @@ -292,18 +292,24 @@ bool Builtins::IsIsolateIndependentBuiltin(const Code code) { } // static -void Builtins::InitializeBuiltinEntryTable(Isolate* isolate) { - EmbeddedData d = EmbeddedData::FromBlob(isolate); - Address* builtin_entry_table = isolate->builtin_entry_table(); - for (Builtin builtin = Builtins::kFirst; builtin <= Builtins::kLast; - ++builtin) { - // TODO(jgruber,chromium:1020986): Remove the CHECK once the linked issue is - // resolved. - CHECK( - Builtins::IsBuiltinId(isolate->heap()->builtin(builtin).builtin_id())); - DCHECK(isolate->heap()->builtin(builtin).is_off_heap_trampoline()); - builtin_entry_table[static_cast(builtin)] = - d.InstructionStartOfBuiltin(builtin); +void Builtins::InitializeIsolateDataTables(Isolate* isolate) { + EmbeddedData embedded_data = EmbeddedData::FromBlob(isolate); + IsolateData* isolate_data = isolate->isolate_data(); + + // The entry table. + for (Builtin i = Builtins::kFirst; i <= Builtins::kLast; ++i) { + DCHECK(Builtins::IsBuiltinId(isolate->heap()->builtin(i).builtin_id())); + DCHECK(isolate->heap()->builtin(i).is_off_heap_trampoline()); + isolate_data->builtin_entry_table()[ToInt(i)] = + embedded_data.InstructionStartOfBuiltin(i); + } + + // T0 tables. + for (Builtin i = Builtins::kFirst; i <= Builtins::kLastTier0; ++i) { + const int ii = ToInt(i); + isolate_data->builtin_tier0_entry_table()[ii] = + isolate_data->builtin_entry_table()[ii]; + isolate_data->builtin_tier0_table()[ii] = isolate_data->builtin_table()[ii]; } } @@ -314,10 +320,10 @@ void Builtins::EmitCodeCreateEvents(Isolate* isolate) { return; // No need to iterate the entire table in this case. } - Address* builtins = isolate->builtins_table(); + Address* builtins = isolate->builtin_table(); int i = 0; HandleScope scope(isolate); - for (; i < static_cast(Builtin::kFirstBytecodeHandler); i++) { + for (; i < ToInt(Builtin::kFirstBytecodeHandler); i++) { Handle code(AbstractCode::cast(Object(builtins[i])), isolate); PROFILE(isolate, CodeCreateEvent(CodeEventListener::BUILTIN_TAG, code, Builtins::name(FromInt(i)))); @@ -420,7 +426,7 @@ Handle Builtins::GenerateOffHeapTrampolineRelocInfo( Builtins::Kind Builtins::KindOf(Builtin builtin) { DCHECK(IsBuiltinId(builtin)); - return builtin_metadata[static_cast(builtin)].kind; + return builtin_metadata[ToInt(builtin)].kind; } // static diff --git a/deps/v8/src/builtins/builtins.h b/deps/v8/src/builtins/builtins.h index 2d6f221ebdd377..e606a3881e1402 100644 --- a/deps/v8/src/builtins/builtins.h +++ b/deps/v8/src/builtins/builtins.h @@ -74,10 +74,14 @@ class Builtins { #define ADD_ONE(Name, ...) +1 static constexpr int kBuiltinCount = 0 BUILTIN_LIST( ADD_ONE, ADD_ONE, ADD_ONE, ADD_ONE, ADD_ONE, ADD_ONE, ADD_ONE); + static constexpr int kBuiltinTier0Count = 0 BUILTIN_LIST_TIER0( + ADD_ONE, ADD_ONE, ADD_ONE, ADD_ONE, ADD_ONE, ADD_ONE, ADD_ONE); #undef ADD_ONE static constexpr Builtin kFirst = static_cast(0); static constexpr Builtin kLast = static_cast(kBuiltinCount - 1); + static constexpr Builtin kLastTier0 = + static_cast(kBuiltinTier0Count - 1); static constexpr int kFirstWideBytecodeHandler = static_cast(Builtin::kFirstBytecodeHandler) + @@ -96,11 +100,18 @@ class Builtins { return static_cast(maybe_id) < static_cast(kBuiltinCount); } + static constexpr bool IsTier0(Builtin builtin) { + return builtin <= kLastTier0 && IsBuiltinId(builtin); + } static constexpr Builtin FromInt(int id) { DCHECK(IsBuiltinId(id)); return static_cast(id); } + static constexpr int ToInt(Builtin id) { + DCHECK(IsBuiltinId(id)); + return static_cast(id); + } // The different builtin kinds are documented in builtins-definitions.h. enum Kind { CPP, TFJ, TFC, TFS, TFH, BCH, ASM }; @@ -195,9 +206,7 @@ class Builtins { return kAllBuiltinsAreIsolateIndependent; } - // Initializes the table of builtin entry points based on the current contents - // of the builtins table. - static void InitializeBuiltinEntryTable(Isolate* isolate); + static void InitializeIsolateDataTables(Isolate* isolate); // Emits a CodeCreateEvent for every builtin. static void EmitCodeCreateEvents(Isolate* isolate); diff --git a/deps/v8/src/codegen/arm/assembler-arm.h b/deps/v8/src/codegen/arm/assembler-arm.h index 4a9fe49685de31..a34b9e1b6626cc 100644 --- a/deps/v8/src/codegen/arm/assembler-arm.h +++ b/deps/v8/src/codegen/arm/assembler-arm.h @@ -1067,7 +1067,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { ~BlockConstPoolScope() { assem_->EndBlockConstPool(); } private: - Assembler* assem_; + Assembler* const assem_; DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstPoolScope); }; @@ -1250,6 +1250,12 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { (pc_offset() < no_const_pool_before_); } + bool has_pending_constants() const { + bool result = !pending_32_bit_constants_.empty(); + DCHECK_EQ(result, first_const_pool_32_use_ != -1); + return result; + } + bool VfpRegisterIsAvailable(DwVfpRegister reg) { DCHECK(reg.is_valid()); return IsEnabled(VFP32DREGS) || diff --git a/deps/v8/src/codegen/arm/macro-assembler-arm.cc b/deps/v8/src/codegen/arm/macro-assembler-arm.cc index 43bbd8620795e4..adeb8748ce254e 100644 --- a/deps/v8/src/codegen/arm/macro-assembler-arm.cc +++ b/deps/v8/src/codegen/arm/macro-assembler-arm.cc @@ -182,7 +182,7 @@ void TurboAssembler::Jump(Handle code, RelocInfo::Mode rmode, // size s.t. pc-relative calls may be used. UseScratchRegisterScope temps(this); Register scratch = temps.Acquire(); - int offset = IsolateData::builtin_entry_slot_offset(code->builtin_id()); + int offset = IsolateData::BuiltinEntrySlotOffset(code->builtin_id()); ldr(scratch, MemOperand(kRootRegister, offset)); Jump(scratch, cond); return; @@ -269,7 +269,7 @@ void TurboAssembler::Call(Handle code, RelocInfo::Mode rmode, // This branch is taken only for specific cctests, where we force isolate // creation at runtime. At this point, Code space isn't restricted to a // size s.t. pc-relative calls may be used. - int offset = IsolateData::builtin_entry_slot_offset(code->builtin_id()); + int offset = IsolateData::BuiltinEntrySlotOffset(code->builtin_id()); ldr(ip, MemOperand(kRootRegister, offset)); Call(ip, cond); return; @@ -315,7 +315,7 @@ MemOperand TurboAssembler::EntryFromBuiltinAsOperand(Builtin builtin) { ASM_CODE_COMMENT(this); DCHECK(root_array_available()); return MemOperand(kRootRegister, - IsolateData::builtin_entry_slot_offset(builtin)); + IsolateData::BuiltinEntrySlotOffset(builtin)); } void TurboAssembler::CallBuiltin(Builtin builtin, Condition cond) { @@ -2671,9 +2671,15 @@ void TurboAssembler::CallForDeoptimization(Builtin target, int, Label* exit, DeoptimizeKind kind, Label* ret, Label*) { ASM_CODE_COMMENT(this); + + // All constants should have been emitted prior to deoptimization exit + // emission. See PrepareForDeoptimizationExits. + DCHECK(!has_pending_constants()); BlockConstPoolScope block_const_pool(this); - ldr(ip, MemOperand(kRootRegister, - IsolateData::builtin_entry_slot_offset(target))); + + CHECK_LE(target, Builtins::kLastTier0); + ldr(ip, + MemOperand(kRootRegister, IsolateData::BuiltinEntrySlotOffset(target))); Call(ip); DCHECK_EQ(SizeOfCodeGeneratedSince(exit), (kind == DeoptimizeKind::kLazy) @@ -2685,6 +2691,9 @@ void TurboAssembler::CallForDeoptimization(Builtin target, int, Label* exit, DCHECK_EQ(SizeOfCodeGeneratedSince(exit), Deoptimizer::kEagerWithResumeBeforeArgsSize); } + + // The above code must not emit constants either. + DCHECK(!has_pending_constants()); } void TurboAssembler::Trap() { stop(); } diff --git a/deps/v8/src/codegen/arm64/macro-assembler-arm64.cc b/deps/v8/src/codegen/arm64/macro-assembler-arm64.cc index 09065414cc6d18..36efeb3d7527a5 100644 --- a/deps/v8/src/codegen/arm64/macro-assembler-arm64.cc +++ b/deps/v8/src/codegen/arm64/macro-assembler-arm64.cc @@ -1965,7 +1965,7 @@ MemOperand TurboAssembler::EntryFromBuiltinAsOperand(Builtin builtin) { ASM_CODE_COMMENT(this); DCHECK(root_array_available()); return MemOperand(kRootRegister, - IsolateData::builtin_entry_slot_offset(builtin)); + IsolateData::BuiltinEntrySlotOffset(builtin)); } void TurboAssembler::CallBuiltinByIndex(Register builtin_index) { diff --git a/deps/v8/src/codegen/ia32/macro-assembler-ia32.cc b/deps/v8/src/codegen/ia32/macro-assembler-ia32.cc index e11d6223eac981..3d22b9fbc8f24b 100644 --- a/deps/v8/src/codegen/ia32/macro-assembler-ia32.cc +++ b/deps/v8/src/codegen/ia32/macro-assembler-ia32.cc @@ -1958,8 +1958,7 @@ void TurboAssembler::CallBuiltin(Builtin builtin) { Operand TurboAssembler::EntryFromBuiltinAsOperand(Builtin builtin) { ASM_CODE_COMMENT(this); - return Operand(kRootRegister, - IsolateData::builtin_entry_slot_offset(builtin)); + return Operand(kRootRegister, IsolateData::BuiltinEntrySlotOffset(builtin)); } void TurboAssembler::LoadCodeObjectEntry(Register destination, diff --git a/deps/v8/src/codegen/loong64/macro-assembler-loong64.cc b/deps/v8/src/codegen/loong64/macro-assembler-loong64.cc index b999c1166be0eb..1710c400518549 100644 --- a/deps/v8/src/codegen/loong64/macro-assembler-loong64.cc +++ b/deps/v8/src/codegen/loong64/macro-assembler-loong64.cc @@ -2768,7 +2768,7 @@ void TurboAssembler::LoadEntryFromBuiltin(Builtin builtin, MemOperand TurboAssembler::EntryFromBuiltinAsOperand(Builtin builtin) { DCHECK(root_array_available()); return MemOperand(kRootRegister, - IsolateData::builtin_entry_slot_offset(builtin)); + IsolateData::BuiltinEntrySlotOffset(builtin)); } void TurboAssembler::CallBuiltinByIndex(Register builtin_index) { @@ -4030,8 +4030,8 @@ void TurboAssembler::CallForDeoptimization(Builtin target, int, Label* exit, DeoptimizeKind kind, Label* ret, Label*) { BlockTrampolinePoolScope block_trampoline_pool(this); - Ld_d(t7, MemOperand(kRootRegister, - IsolateData::builtin_entry_slot_offset(target))); + Ld_d(t7, + MemOperand(kRootRegister, IsolateData::BuiltinEntrySlotOffset(target))); Call(t7); DCHECK_EQ(SizeOfCodeGeneratedSince(exit), (kind == DeoptimizeKind::kLazy) diff --git a/deps/v8/src/codegen/mips/macro-assembler-mips.cc b/deps/v8/src/codegen/mips/macro-assembler-mips.cc index 32f85c6ec2b2a5..d30e5ee2e104d3 100644 --- a/deps/v8/src/codegen/mips/macro-assembler-mips.cc +++ b/deps/v8/src/codegen/mips/macro-assembler-mips.cc @@ -3975,7 +3975,7 @@ void TurboAssembler::LoadEntryFromBuiltin(Builtin builtin, MemOperand TurboAssembler::EntryFromBuiltinAsOperand(Builtin builtin) { DCHECK(root_array_available()); return MemOperand(kRootRegister, - IsolateData::builtin_entry_slot_offset(builtin)); + IsolateData::BuiltinEntrySlotOffset(builtin)); } void TurboAssembler::CallBuiltinByIndex(Register builtin_index) { @@ -5525,7 +5525,7 @@ void TurboAssembler::CallForDeoptimization(Builtin target, int, Label* exit, Label*) { BlockTrampolinePoolScope block_trampoline_pool(this); Lw(t9, - MemOperand(kRootRegister, IsolateData::builtin_entry_slot_offset(target))); + MemOperand(kRootRegister, IsolateData::BuiltinEntrySlotOffset(target))); Call(t9); DCHECK_EQ(SizeOfCodeGeneratedSince(exit), (kind == DeoptimizeKind::kLazy) diff --git a/deps/v8/src/codegen/mips64/macro-assembler-mips64.cc b/deps/v8/src/codegen/mips64/macro-assembler-mips64.cc index 5ceb69e861c264..3cf1ec9fd2e317 100644 --- a/deps/v8/src/codegen/mips64/macro-assembler-mips64.cc +++ b/deps/v8/src/codegen/mips64/macro-assembler-mips64.cc @@ -4465,7 +4465,7 @@ void TurboAssembler::LoadEntryFromBuiltin(Builtin builtin, MemOperand TurboAssembler::EntryFromBuiltinAsOperand(Builtin builtin) { DCHECK(root_array_available()); return MemOperand(kRootRegister, - IsolateData::builtin_entry_slot_offset(builtin)); + IsolateData::BuiltinEntrySlotOffset(builtin)); } void TurboAssembler::CallBuiltinByIndex(Register builtin_index) { @@ -6065,7 +6065,7 @@ void TurboAssembler::CallForDeoptimization(Builtin target, int, Label* exit, Label*) { BlockTrampolinePoolScope block_trampoline_pool(this); Ld(t9, - MemOperand(kRootRegister, IsolateData::builtin_entry_slot_offset(target))); + MemOperand(kRootRegister, IsolateData::BuiltinEntrySlotOffset(target))); Call(t9); DCHECK_EQ(SizeOfCodeGeneratedSince(exit), (kind == DeoptimizeKind::kLazy) diff --git a/deps/v8/src/codegen/ppc/macro-assembler-ppc.cc b/deps/v8/src/codegen/ppc/macro-assembler-ppc.cc index 64d94c68eb582c..a1ba6f8ddff1fd 100644 --- a/deps/v8/src/codegen/ppc/macro-assembler-ppc.cc +++ b/deps/v8/src/codegen/ppc/macro-assembler-ppc.cc @@ -187,15 +187,14 @@ void TurboAssembler::Jump(Handle code, RelocInfo::Mode rmode, DCHECK_IMPLIES(options().isolate_independent_code, Builtins::IsIsolateIndependentBuiltin(*code)); - Builtin builtin_index = Builtin::kNoBuiltinId; + Builtin builtin = Builtin::kNoBuiltinId; bool target_is_builtin = - isolate()->builtins()->IsBuiltinHandle(code, &builtin_index); + isolate()->builtins()->IsBuiltinHandle(code, &builtin); if (root_array_available_ && options().isolate_independent_code) { Label skip; Register scratch = ip; - int offset = static_cast(code->builtin_id()) * kSystemPointerSize + - IsolateData::builtin_entry_table_offset(); + int offset = IsolateData::BuiltinEntrySlotOffset(code->builtin_id()); LoadU64(scratch, MemOperand(kRootRegister, offset), r0); if (cond != al) b(NegateCondition(cond), &skip, cr); Jump(scratch); @@ -204,10 +203,10 @@ void TurboAssembler::Jump(Handle code, RelocInfo::Mode rmode, } else if (options().inline_offheap_trampolines && target_is_builtin) { // Inline the trampoline. Label skip; - RecordCommentForOffHeapTrampoline(builtin_index); + RecordCommentForOffHeapTrampoline(builtin); // Use ip directly instead of using UseScratchRegisterScope, as we do // not preserve scratch registers across calls. - mov(ip, Operand(BuiltinEntry(builtin_index), RelocInfo::OFF_HEAP_TARGET)); + mov(ip, Operand(BuiltinEntry(builtin), RelocInfo::OFF_HEAP_TARGET)); if (cond != al) b(NegateCondition(cond), &skip, cr); Jump(ip); bind(&skip); @@ -274,14 +273,13 @@ void TurboAssembler::Call(Handle code, RelocInfo::Mode rmode, DCHECK_IMPLIES(options().use_pc_relative_calls_and_jumps, Builtins::IsIsolateIndependentBuiltin(*code)); - Builtin builtin_index = Builtin::kNoBuiltinId; + Builtin builtin = Builtin::kNoBuiltinId; bool target_is_builtin = - isolate()->builtins()->IsBuiltinHandle(code, &builtin_index); + isolate()->builtins()->IsBuiltinHandle(code, &builtin); if (root_array_available_ && options().isolate_independent_code) { Label skip; - int offset = static_cast(code->builtin_id()) * kSystemPointerSize + - IsolateData::builtin_entry_table_offset(); + int offset = IsolateData::BuiltinEntrySlotOffset(code->builtin_id()); LoadU64(ip, MemOperand(kRootRegister, offset)); if (cond != al) b(NegateCondition(cond), &skip); Call(ip); @@ -289,14 +287,7 @@ void TurboAssembler::Call(Handle code, RelocInfo::Mode rmode, return; } else if (options().inline_offheap_trampolines && target_is_builtin) { // Inline the trampoline. - RecordCommentForOffHeapTrampoline(builtin_index); - // Use ip directly instead of using UseScratchRegisterScope, as we do - // not preserve scratch registers across calls. - mov(ip, Operand(BuiltinEntry(builtin_index), RelocInfo::OFF_HEAP_TARGET)); - Label skip; - if (cond != al) b(NegateCondition(cond), &skip); - Call(ip); - bind(&skip); + CallBuiltin(builtin, cond); return; } DCHECK(code->IsExecutable()); @@ -304,6 +295,18 @@ void TurboAssembler::Call(Handle code, RelocInfo::Mode rmode, Call(static_cast
(target_index), rmode, cond); } +void TurboAssembler::CallBuiltin(Builtin builtin, Condition cond) { + ASM_CODE_COMMENT_STRING(this, CommentForOffHeapTrampoline("call", builtin)); + DCHECK(Builtins::IsBuiltinId(builtin)); + // Use ip directly instead of using UseScratchRegisterScope, as we do not + // preserve scratch registers across calls. + mov(ip, Operand(BuiltinEntry(builtin), RelocInfo::OFF_HEAP_TARGET)); + Label skip; + if (cond != al) b(NegateCondition(cond), &skip); + Call(ip); + bind(&skip); +} + void TurboAssembler::Drop(int count) { if (count > 0) { AddS64(sp, sp, Operand(count * kSystemPointerSize), r0); @@ -3638,8 +3641,9 @@ void TurboAssembler::CallForDeoptimization(Builtin target, int, Label* exit, DeoptimizeKind kind, Label* ret, Label*) { BlockTrampolinePoolScope block_trampoline_pool(this); + CHECK_LE(target, Builtins::kLastTier0); LoadU64(ip, MemOperand(kRootRegister, - IsolateData::builtin_entry_slot_offset(target))); + IsolateData::BuiltinEntrySlotOffset(target))); Call(ip); DCHECK_EQ(SizeOfCodeGeneratedSince(exit), (kind == DeoptimizeKind::kLazy) diff --git a/deps/v8/src/codegen/ppc/macro-assembler-ppc.h b/deps/v8/src/codegen/ppc/macro-assembler-ppc.h index 2dfdb39dcc1e2a..4a28b8838490ad 100644 --- a/deps/v8/src/codegen/ppc/macro-assembler-ppc.h +++ b/deps/v8/src/codegen/ppc/macro-assembler-ppc.h @@ -49,6 +49,7 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { public: using TurboAssemblerBase::TurboAssemblerBase; + void CallBuiltin(Builtin builtin, Condition cond); void Popcnt32(Register dst, Register src); void Popcnt64(Register dst, Register src); // Converts the integer (untagged smi) in |src| to a double, storing diff --git a/deps/v8/src/codegen/riscv64/macro-assembler-riscv64.cc b/deps/v8/src/codegen/riscv64/macro-assembler-riscv64.cc index 0e0d8bda5a8535..f010195890dd1f 100644 --- a/deps/v8/src/codegen/riscv64/macro-assembler-riscv64.cc +++ b/deps/v8/src/codegen/riscv64/macro-assembler-riscv64.cc @@ -3355,7 +3355,7 @@ void TurboAssembler::LoadEntryFromBuiltin(Builtin builtin, MemOperand TurboAssembler::EntryFromBuiltinAsOperand(Builtin builtin) { DCHECK(root_array_available()); return MemOperand(kRootRegister, - IsolateData::builtin_entry_slot_offset(builtin)); + IsolateData::BuiltinEntrySlotOffset(builtin)); } void TurboAssembler::PatchAndJump(Address target) { @@ -4824,7 +4824,7 @@ void TurboAssembler::CallForDeoptimization(Builtin target, int, Label* exit, Label*) { BlockTrampolinePoolScope block_trampoline_pool(this); Ld(t6, - MemOperand(kRootRegister, IsolateData::builtin_entry_slot_offset(target))); + MemOperand(kRootRegister, IsolateData::BuiltinEntrySlotOffset(target))); Call(t6); DCHECK_EQ(SizeOfCodeGeneratedSince(exit), (kind == DeoptimizeKind::kLazy) diff --git a/deps/v8/src/codegen/s390/macro-assembler-s390.cc b/deps/v8/src/codegen/s390/macro-assembler-s390.cc index a6c55746f8dfdc..b7b582d5a5dbfc 100644 --- a/deps/v8/src/codegen/s390/macro-assembler-s390.cc +++ b/deps/v8/src/codegen/s390/macro-assembler-s390.cc @@ -416,14 +416,14 @@ void TurboAssembler::Jump(Handle code, RelocInfo::Mode rmode, DCHECK_IMPLIES(options().isolate_independent_code, Builtins::IsIsolateIndependentBuiltin(*code)); - Builtin builtin_index = Builtin::kNoBuiltinId; + Builtin builtin = Builtin::kNoBuiltinId; bool target_is_builtin = - isolate()->builtins()->IsBuiltinHandle(code, &builtin_index); + isolate()->builtins()->IsBuiltinHandle(code, &builtin); if (options().inline_offheap_trampolines && target_is_builtin) { // Inline the trampoline. - RecordCommentForOffHeapTrampoline(builtin_index); - mov(ip, Operand(BuiltinEntry(builtin_index), RelocInfo::OFF_HEAP_TARGET)); + RecordCommentForOffHeapTrampoline(builtin); + mov(ip, Operand(BuiltinEntry(builtin), RelocInfo::OFF_HEAP_TARGET)); b(cond, ip); return; } @@ -474,21 +474,28 @@ void TurboAssembler::Call(Handle code, RelocInfo::Mode rmode, DCHECK_IMPLIES(options().isolate_independent_code, Builtins::IsIsolateIndependentBuiltin(*code)); - Builtin builtin_index = Builtin::kNoBuiltinId; + Builtin builtin = Builtin::kNoBuiltinId; bool target_is_builtin = - isolate()->builtins()->IsBuiltinHandle(code, &builtin_index); + isolate()->builtins()->IsBuiltinHandle(code, &builtin); if (target_is_builtin && options().inline_offheap_trampolines) { // Inline the trampoline. - RecordCommentForOffHeapTrampoline(builtin_index); - mov(ip, Operand(BuiltinEntry(builtin_index), RelocInfo::OFF_HEAP_TARGET)); - Call(ip); + CallBuiltin(builtin); return; } DCHECK(code->IsExecutable()); call(code, rmode); } +void TurboAssembler::CallBuiltin(Builtin builtin) { + ASM_CODE_COMMENT_STRING(this, CommentForOffHeapTrampoline("call", builtin)); + DCHECK(Builtins::IsBuiltinId(builtin)); + // Use ip directly instead of using UseScratchRegisterScope, as we do not + // preserve scratch registers across calls. + mov(ip, Operand(BuiltinEntry(builtin), RelocInfo::OFF_HEAP_TARGET)); + Call(ip); +} + void TurboAssembler::Drop(int count) { if (count > 0) { int total = count * kSystemPointerSize; @@ -4975,8 +4982,9 @@ void TurboAssembler::StoreReturnAddressAndCall(Register target) { void TurboAssembler::CallForDeoptimization(Builtin target, int, Label* exit, DeoptimizeKind kind, Label* ret, Label*) { + ASM_CODE_COMMENT(this); LoadU64(ip, MemOperand(kRootRegister, - IsolateData::builtin_entry_slot_offset(target))); + IsolateData::BuiltinEntrySlotOffset(target))); Call(ip); DCHECK_EQ(SizeOfCodeGeneratedSince(exit), (kind == DeoptimizeKind::kLazy) diff --git a/deps/v8/src/codegen/s390/macro-assembler-s390.h b/deps/v8/src/codegen/s390/macro-assembler-s390.h index b7123d596065c2..ab105d5eb43558 100644 --- a/deps/v8/src/codegen/s390/macro-assembler-s390.h +++ b/deps/v8/src/codegen/s390/macro-assembler-s390.h @@ -44,6 +44,7 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { public: using TurboAssemblerBase::TurboAssemblerBase; + void CallBuiltin(Builtin builtin); void AtomicCmpExchangeHelper(Register addr, Register output, Register old_value, Register new_value, int start, int end, int shift_amount, int offset, diff --git a/deps/v8/src/codegen/turbo-assembler.cc b/deps/v8/src/codegen/turbo-assembler.cc index 59de4733ffb16f..09c4559813b076 100644 --- a/deps/v8/src/codegen/turbo-assembler.cc +++ b/deps/v8/src/codegen/turbo-assembler.cc @@ -97,7 +97,7 @@ int32_t TurboAssemblerBase::RootRegisterOffsetForRootIndex( // static int32_t TurboAssemblerBase::RootRegisterOffsetForBuiltin(Builtin builtin) { - return IsolateData::builtin_slot_offset(builtin); + return IsolateData::BuiltinSlotOffset(builtin); } // static diff --git a/deps/v8/src/codegen/x64/macro-assembler-x64.cc b/deps/v8/src/codegen/x64/macro-assembler-x64.cc index f4c498dc10da5f..c453d783894891 100644 --- a/deps/v8/src/codegen/x64/macro-assembler-x64.cc +++ b/deps/v8/src/codegen/x64/macro-assembler-x64.cc @@ -1915,8 +1915,7 @@ void TurboAssembler::Call(Handle code_object, RelocInfo::Mode rmode) { Operand TurboAssembler::EntryFromBuiltinAsOperand(Builtin builtin) { DCHECK(root_array_available()); - return Operand(kRootRegister, - IsolateData::builtin_entry_slot_offset(builtin)); + return Operand(kRootRegister, IsolateData::BuiltinEntrySlotOffset(builtin)); } Operand TurboAssembler::EntryFromBuiltinIndexAsOperand(Register builtin_index) { diff --git a/deps/v8/src/compiler/wasm-compiler.cc b/deps/v8/src/compiler/wasm-compiler.cc index f6f6c3844f31eb..b3d6e7bb74b9c5 100644 --- a/deps/v8/src/compiler/wasm-compiler.cc +++ b/deps/v8/src/compiler/wasm-compiler.cc @@ -3574,7 +3574,7 @@ Node* WasmGraphBuilder::BuildCallToRuntimeWithContext(Runtime::FunctionId f, Builtin::kCEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit; Node* centry_stub = gasm_->LoadFromObject(MachineType::Pointer(), isolate_root, - IsolateData::builtin_slot_offset(centry_id)); + IsolateData::BuiltinSlotOffset(centry_id)); // TODO(titzer): allow arbitrary number of runtime arguments // At the moment we only allow 5 parameters. If more parameters are needed, // increase this constant accordingly. diff --git a/deps/v8/src/deoptimizer/arm/deoptimizer-arm.cc b/deps/v8/src/deoptimizer/arm/deoptimizer-arm.cc index f3353b5689ce4b..d0843f43e9eedd 100644 --- a/deps/v8/src/deoptimizer/arm/deoptimizer-arm.cc +++ b/deps/v8/src/deoptimizer/arm/deoptimizer-arm.cc @@ -3,10 +3,23 @@ // found in the LICENSE file. #include "src/deoptimizer/deoptimizer.h" +#include "src/execution/isolate-data.h" namespace v8 { namespace internal { +// The deopt exit sizes below depend on the following IsolateData layout +// guarantees: +#define ASSERT_OFFSET(BuiltinName) \ + STATIC_ASSERT(IsolateData::builtin_tier0_entry_table_offset() + \ + Builtins::ToInt(BuiltinName) * kSystemPointerSize <= \ + 0x1000) +ASSERT_OFFSET(Builtin::kDeoptimizationEntry_Eager); +ASSERT_OFFSET(Builtin::kDeoptimizationEntry_Lazy); +ASSERT_OFFSET(Builtin::kDeoptimizationEntry_Soft); +ASSERT_OFFSET(Builtin::kDeoptimizationEntry_Bailout); +#undef ASSERT_OFFSET + const bool Deoptimizer::kSupportsFixedDeoptExitSizes = true; const int Deoptimizer::kNonLazyDeoptExitSize = 2 * kInstrSize; const int Deoptimizer::kLazyDeoptExitSize = 2 * kInstrSize; diff --git a/deps/v8/src/deoptimizer/ppc/deoptimizer-ppc.cc b/deps/v8/src/deoptimizer/ppc/deoptimizer-ppc.cc index cde68050628267..d7cd04bdf74910 100644 --- a/deps/v8/src/deoptimizer/ppc/deoptimizer-ppc.cc +++ b/deps/v8/src/deoptimizer/ppc/deoptimizer-ppc.cc @@ -2,15 +2,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "src/codegen/assembler-inl.h" -#include "src/codegen/macro-assembler.h" -#include "src/codegen/register-configuration.h" -#include "src/codegen/safepoint-table.h" #include "src/deoptimizer/deoptimizer.h" +#include "src/execution/isolate-data.h" namespace v8 { namespace internal { +// The deopt exit sizes below depend on the following IsolateData layout +// guarantees: +#define ASSERT_OFFSET(BuiltinName) \ + STATIC_ASSERT(IsolateData::builtin_tier0_entry_table_offset() + \ + Builtins::ToInt(BuiltinName) * kSystemPointerSize <= \ + 0x1000) +ASSERT_OFFSET(Builtin::kDeoptimizationEntry_Eager); +ASSERT_OFFSET(Builtin::kDeoptimizationEntry_Lazy); +ASSERT_OFFSET(Builtin::kDeoptimizationEntry_Soft); +ASSERT_OFFSET(Builtin::kDeoptimizationEntry_Bailout); +#undef ASSERT_OFFSET + const bool Deoptimizer::kSupportsFixedDeoptExitSizes = true; const int Deoptimizer::kNonLazyDeoptExitSize = 3 * kInstrSize; const int Deoptimizer::kLazyDeoptExitSize = 3 * kInstrSize; diff --git a/deps/v8/src/deoptimizer/riscv64/deoptimizer-riscv64.cc b/deps/v8/src/deoptimizer/riscv64/deoptimizer-riscv64.cc index b7dceed503d191..12573ed29bef5a 100644 --- a/deps/v8/src/deoptimizer/riscv64/deoptimizer-riscv64.cc +++ b/deps/v8/src/deoptimizer/riscv64/deoptimizer-riscv64.cc @@ -8,9 +8,9 @@ namespace v8 { namespace internal { const bool Deoptimizer::kSupportsFixedDeoptExitSizes = true; -const int Deoptimizer::kNonLazyDeoptExitSize = 4 * kInstrSize; -const int Deoptimizer::kLazyDeoptExitSize = 4 * kInstrSize; -const int Deoptimizer::kEagerWithResumeBeforeArgsSize = 5 * kInstrSize; +const int Deoptimizer::kNonLazyDeoptExitSize = 2 * kInstrSize; +const int Deoptimizer::kLazyDeoptExitSize = 2 * kInstrSize; +const int Deoptimizer::kEagerWithResumeBeforeArgsSize = 3 * kInstrSize; const int Deoptimizer::kEagerWithResumeDeoptExitSize = kEagerWithResumeBeforeArgsSize + 4 * kInstrSize; const int Deoptimizer::kEagerWithResumeImmedArgs1PcOffset = kInstrSize; diff --git a/deps/v8/src/deoptimizer/s390/deoptimizer-s390.cc b/deps/v8/src/deoptimizer/s390/deoptimizer-s390.cc index 54e450f3e88e4a..c776bdb48b2dd1 100644 --- a/deps/v8/src/deoptimizer/s390/deoptimizer-s390.cc +++ b/deps/v8/src/deoptimizer/s390/deoptimizer-s390.cc @@ -3,10 +3,23 @@ // found in the LICENSE file. #include "src/deoptimizer/deoptimizer.h" +#include "src/execution/isolate-data.h" namespace v8 { namespace internal { +// The deopt exit sizes below depend on the following IsolateData layout +// guarantees: +#define ASSERT_OFFSET(BuiltinName) \ + STATIC_ASSERT(IsolateData::builtin_tier0_entry_table_offset() + \ + Builtins::ToInt(BuiltinName) * kSystemPointerSize <= \ + 0x1000) +ASSERT_OFFSET(Builtin::kDeoptimizationEntry_Eager); +ASSERT_OFFSET(Builtin::kDeoptimizationEntry_Lazy); +ASSERT_OFFSET(Builtin::kDeoptimizationEntry_Soft); +ASSERT_OFFSET(Builtin::kDeoptimizationEntry_Bailout); +#undef ASSERT_OFFSET + const bool Deoptimizer::kSupportsFixedDeoptExitSizes = true; const int Deoptimizer::kNonLazyDeoptExitSize = 6 + 2; const int Deoptimizer::kLazyDeoptExitSize = 6 + 2; diff --git a/deps/v8/src/deoptimizer/x64/deoptimizer-x64.cc b/deps/v8/src/deoptimizer/x64/deoptimizer-x64.cc index 8a95afdc35c378..484ede213ad98f 100644 --- a/deps/v8/src/deoptimizer/x64/deoptimizer-x64.cc +++ b/deps/v8/src/deoptimizer/x64/deoptimizer-x64.cc @@ -5,14 +5,27 @@ #if V8_TARGET_ARCH_X64 #include "src/deoptimizer/deoptimizer.h" +#include "src/execution/isolate-data.h" namespace v8 { namespace internal { +// The deopt exit sizes below depend on the following IsolateData layout +// guarantees: +#define ASSERT_OFFSET(BuiltinName) \ + STATIC_ASSERT(IsolateData::builtin_tier0_entry_table_offset() + \ + Builtins::ToInt(BuiltinName) * kSystemPointerSize <= \ + 0x7F) +ASSERT_OFFSET(Builtin::kDeoptimizationEntry_Eager); +ASSERT_OFFSET(Builtin::kDeoptimizationEntry_Lazy); +ASSERT_OFFSET(Builtin::kDeoptimizationEntry_Soft); +ASSERT_OFFSET(Builtin::kDeoptimizationEntry_Bailout); +#undef ASSERT_OFFSET + const bool Deoptimizer::kSupportsFixedDeoptExitSizes = true; -const int Deoptimizer::kNonLazyDeoptExitSize = 7; -const int Deoptimizer::kLazyDeoptExitSize = 7; -const int Deoptimizer::kEagerWithResumeBeforeArgsSize = 12; +const int Deoptimizer::kNonLazyDeoptExitSize = 4; +const int Deoptimizer::kLazyDeoptExitSize = 4; +const int Deoptimizer::kEagerWithResumeBeforeArgsSize = 9; const int Deoptimizer::kEagerWithResumeDeoptExitSize = kEagerWithResumeBeforeArgsSize + 2 * kSystemPointerSize; const int Deoptimizer::kEagerWithResumeImmedArgs1PcOffset = 5; diff --git a/deps/v8/src/diagnostics/disassembler.cc b/deps/v8/src/diagnostics/disassembler.cc index 596362b351a43a..928fe1f3576ed5 100644 --- a/deps/v8/src/diagnostics/disassembler.cc +++ b/deps/v8/src/diagnostics/disassembler.cc @@ -128,8 +128,11 @@ const char* V8NameConverter::RootRelativeName(int offset) const { const unsigned kRootsTableSize = sizeof(RootsTable); const int kExtRefsTableStart = IsolateData::external_reference_table_offset(); const unsigned kExtRefsTableSize = ExternalReferenceTable::kSizeInBytes; - const int kBuiltinsTableStart = IsolateData::builtins_table_offset(); - const unsigned kBuiltinsTableSize = + const int kBuiltinTier0TableStart = IsolateData::builtin_tier0_table_offset(); + const unsigned kBuiltinTier0TableSize = + Builtins::kBuiltinTier0Count * kSystemPointerSize; + const int kBuiltinTableStart = IsolateData::builtin_table_offset(); + const unsigned kBuiltinTableSize = Builtins::kBuiltinCount * kSystemPointerSize; if (static_cast(offset - kRootsTableStart) < kRootsTableSize) { @@ -143,7 +146,6 @@ const char* V8NameConverter::RootRelativeName(int offset) const { SNPrintF(v8_buffer_, "root (%s)", RootsTable::name(root_index)); return v8_buffer_.begin(); - } else if (static_cast(offset - kExtRefsTableStart) < kExtRefsTableSize) { uint32_t offset_in_extref_table = offset - kExtRefsTableStart; @@ -162,17 +164,24 @@ const char* V8NameConverter::RootRelativeName(int offset) const { isolate_->external_reference_table()->NameFromOffset( offset_in_extref_table)); return v8_buffer_.begin(); - - } else if (static_cast(offset - kBuiltinsTableStart) < - kBuiltinsTableSize) { - uint32_t offset_in_builtins_table = (offset - kBuiltinsTableStart); + } else if (static_cast(offset - kBuiltinTier0TableStart) < + kBuiltinTier0TableSize) { + uint32_t offset_in_builtins_table = (offset - kBuiltinTier0TableStart); Builtin builtin = Builtins::FromInt(offset_in_builtins_table / kSystemPointerSize); const char* name = Builtins::name(builtin); SNPrintF(v8_buffer_, "builtin (%s)", name); return v8_buffer_.begin(); + } else if (static_cast(offset - kBuiltinTableStart) < + kBuiltinTableSize) { + uint32_t offset_in_builtins_table = (offset - kBuiltinTableStart); + Builtin builtin = + Builtins::FromInt(offset_in_builtins_table / kSystemPointerSize); + const char* name = Builtins::name(builtin); + SNPrintF(v8_buffer_, "builtin (%s)", name); + return v8_buffer_.begin(); } else { // It must be a direct access to one of the external values. if (directly_accessed_external_refs_.empty()) { diff --git a/deps/v8/src/execution/frames.cc b/deps/v8/src/execution/frames.cc index a388130ee3c861..7c281458819899 100644 --- a/deps/v8/src/execution/frames.cc +++ b/deps/v8/src/execution/frames.cc @@ -346,7 +346,8 @@ SafeStackFrameIterator::SafeStackFrameIterator(Isolate* isolate, Address pc, top_frame_type_ = type; state.fp = fast_c_fp; state.sp = sp; - state.pc_address = isolate->isolate_data()->fast_c_call_caller_pc_address(); + state.pc_address = reinterpret_cast( + isolate->isolate_data()->fast_c_call_caller_pc_address()); advance_frame = false; } else if (IsValidTop(top)) { type = ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state); diff --git a/deps/v8/src/execution/isolate-data.h b/deps/v8/src/execution/isolate-data.h index 3b667e0d5a2183..1fdb2e69edacdf 100644 --- a/deps/v8/src/execution/isolate-data.h +++ b/deps/v8/src/execution/isolate-data.h @@ -20,13 +20,48 @@ namespace internal { class Isolate; +// IsolateData fields, defined as: V(Offset, Size, Name) +#define ISOLATE_DATA_FIELDS(V) \ + /* Misc. fields. */ \ + V(kCageBaseOffset, kSystemPointerSize, cage_base) \ + V(kStackGuardOffset, StackGuard::kSizeInBytes, stack_guard) \ + /* Tier 0 tables (small but fast access). */ \ + V(kBuiltinTier0EntryTableOffset, \ + Builtins::kBuiltinTier0Count* kSystemPointerSize, \ + builtin_tier0_entry_table) \ + V(kBuiltinsTier0TableOffset, \ + Builtins::kBuiltinTier0Count* kSystemPointerSize, builtin_tier0_table) \ + /* Misc. fields. */ \ + V(kEmbedderDataOffset, Internals::kNumIsolateDataSlots* kSystemPointerSize, \ + embedder_data) \ + V(kFastCCallCallerFPOffset, kSystemPointerSize, fast_c_call_caller_fp) \ + V(kFastCCallCallerPCOffset, kSystemPointerSize, fast_c_call_caller_pc) \ + V(kFastApiCallTargetOffset, kSystemPointerSize, fast_api_call_target) \ + V(kLongTaskStatsCounterOffset, kSizetSize, long_task_stats_counter) \ + /* Full tables (arbitrary size, potentially slower access). */ \ + V(kRootsTableOffset, RootsTable::kEntriesCount* kSystemPointerSize, \ + roots_table) \ + V(kExternalReferenceTableOffset, ExternalReferenceTable::kSizeInBytes, \ + external_reference_table) \ + V(kThreadLocalTopOffset, ThreadLocalTop::kSizeInBytes, thread_local_top) \ + V(kBuiltinEntryTableOffset, Builtins::kBuiltinCount* kSystemPointerSize, \ + builtin_entry_table) \ + V(kBuiltinTableOffset, Builtins::kBuiltinCount* kSystemPointerSize, \ + builtin_table) \ + ISOLATE_DATA_FIELDS_HEAP_SANDBOX(V) \ + V(kStackIsIterableOffset, kUInt8Size, stack_is_iterable) + +#ifdef V8_HEAP_SANDBOX +#define ISOLATE_DATA_FIELDS_HEAP_SANDBOX(V) \ + V(kExternalPointerTableOffset, kSystemPointerSize * 3, external_pointer_table) +#else +#define ISOLATE_DATA_FIELDS_HEAP_SANDBOX(V) +#endif // V8_HEAP_SANDBOX + // This class contains a collection of data accessible from both C++ runtime -// and compiled code (including assembly stubs, builtins, interpreter bytecode -// handlers and optimized code). -// In particular, it contains pointer to the V8 heap roots table, external -// reference table and builtins array. -// The compiled code accesses the isolate data fields indirectly via the root -// register. +// and compiled code (including builtins, interpreter bytecode handlers and +// optimized code). The compiled code accesses the isolate data fields +// indirectly via the root register. class IsolateData final { public: IsolateData(Isolate* isolate, Address cage_base) @@ -37,158 +72,103 @@ class IsolateData final { static constexpr intptr_t kIsolateRootBias = kRootRegisterBias; - // The value of kPointerCageBaseRegister - Address cage_base() const { - return COMPRESS_POINTERS_BOOL ? cage_base_ : kNullAddress; - } - // The value of the kRootRegister. Address isolate_root() const { return reinterpret_cast
(this) + kIsolateRootBias; } - // Root-register-relative offset of the roots table. - static constexpr int roots_table_offset() { - return kRootsTableOffset - kIsolateRootBias; - } + // Root-register-relative offsets. + +#define V(Offset, Size, Name) \ + static constexpr int Name##_offset() { return Offset - kIsolateRootBias; } + ISOLATE_DATA_FIELDS(V) +#undef V - // Root-register-relative offset of the given root table entry. static constexpr int root_slot_offset(RootIndex root_index) { return roots_table_offset() + RootsTable::offset_of(root_index); } - // Root-register-relative offset of the external reference table. - static constexpr int external_reference_table_offset() { - return kExternalReferenceTableOffset - kIsolateRootBias; + static constexpr int BuiltinEntrySlotOffset(Builtin id) { + DCHECK(Builtins::IsBuiltinId(id)); + return (Builtins::IsTier0(id) ? builtin_tier0_entry_table_offset() + : builtin_entry_table_offset()) + + Builtins::ToInt(id) * kSystemPointerSize; } - - // Root-register-relative offset of the builtin entry table. - static constexpr int builtin_entry_table_offset() { - return kBuiltinEntryTableOffset - kIsolateRootBias; - } - static constexpr int builtin_entry_slot_offset(Builtin builtin) { - DCHECK(Builtins::IsBuiltinId(builtin)); - return builtin_entry_table_offset() + - static_cast(builtin) * kSystemPointerSize; - } - - // Root-register-relative offset of the builtins table. - static constexpr int builtins_table_offset() { - return kBuiltinsTableOffset - kIsolateRootBias; - } - - // Root-register-relative offset of the external pointer table. -#ifdef V8_HEAP_SANDBOX - static constexpr int external_pointer_table_offset() { - return kExternalPointerTableOffset - kIsolateRootBias; - } -#endif - - static constexpr int fast_c_call_caller_fp_offset() { - return kFastCCallCallerFPOffset - kIsolateRootBias; - } - - static constexpr int fast_c_call_caller_pc_offset() { - return kFastCCallCallerPCOffset - kIsolateRootBias; - } - - static constexpr int fast_api_call_target_offset() { - return kFastApiCallTargetOffset - kIsolateRootBias; + // TODO(ishell): remove in favour of typified id version. + static constexpr int builtin_slot_offset(int builtin_index) { + return BuiltinSlotOffset(Builtins::FromInt(builtin_index)); } - - static constexpr int cage_base_offset() { - return kCageBaseOffset - kIsolateRootBias; + static constexpr int BuiltinSlotOffset(Builtin id) { + return (Builtins::IsTier0(id) ? builtin_tier0_table_offset() + : builtin_table_offset()) + + Builtins::ToInt(id) * kSystemPointerSize; } - // Root-register-relative offset of the given builtin table entry. - // TODO(ishell): remove in favour of typified id version. - static int builtin_slot_offset(int builtin_index) { - DCHECK(Builtins::IsBuiltinId(builtin_index)); - return builtins_table_offset() + builtin_index * kSystemPointerSize; - } +#define V(Offset, Size, Name) \ + Address Name##_address() { return reinterpret_cast
(&Name##_); } + ISOLATE_DATA_FIELDS(V) +#undef V - // Root-register-relative offset of the builtin table entry. - static int builtin_slot_offset(Builtin id) { - return builtins_table_offset() + static_cast(id) * kSystemPointerSize; + Address fast_c_call_caller_fp() const { return fast_c_call_caller_fp_; } + Address fast_c_call_caller_pc() const { return fast_c_call_caller_pc_; } + Address fast_api_call_target() const { return fast_api_call_target_; } + // The value of kPointerCageBaseRegister. + Address cage_base() const { return cage_base_; } + StackGuard* stack_guard() { return &stack_guard_; } + Address* builtin_tier0_entry_table() { return builtin_tier0_entry_table_; } + Address* builtin_tier0_table() { return builtin_tier0_table_; } + RootsTable& roots() { return roots_table_; } + const RootsTable& roots() const { return roots_table_; } + ExternalReferenceTable* external_reference_table() { + return &external_reference_table_; } + ThreadLocalTop& thread_local_top() { return thread_local_top_; } + ThreadLocalTop const& thread_local_top() const { return thread_local_top_; } + Address* builtin_entry_table() { return builtin_entry_table_; } + Address* builtin_table() { return builtin_table_; } + uint8_t stack_is_iterable() const { return stack_is_iterable_; } - // The FP and PC that are saved right before TurboAssembler::CallCFunction. - Address* fast_c_call_caller_fp_address() { return &fast_c_call_caller_fp_; } - Address* fast_c_call_caller_pc_address() { return &fast_c_call_caller_pc_; } - // The address of the fast API callback right before it's executed from - // generated code. - Address* fast_api_call_target_address() { return &fast_api_call_target_; } - StackGuard* stack_guard() { return &stack_guard_; } - uint8_t* stack_is_iterable_address() { return &stack_is_iterable_; } - Address fast_c_call_caller_fp() { return fast_c_call_caller_fp_; } - Address fast_c_call_caller_pc() { return fast_c_call_caller_pc_; } - Address fast_api_call_target() { return fast_api_call_target_; } - uint8_t stack_is_iterable() { return stack_is_iterable_; } - - // Returns true if this address points to data stored in this instance. - // If it's the case then the value can be accessed indirectly through the - // root register. + // Returns true if this address points to data stored in this instance. If + // it's the case then the value can be accessed indirectly through the root + // register. bool contains(Address address) const { STATIC_ASSERT(std::is_unsigned
::value); Address start = reinterpret_cast
(this); return (address - start) < sizeof(*this); } - ThreadLocalTop& thread_local_top() { return thread_local_top_; } - ThreadLocalTop const& thread_local_top() const { return thread_local_top_; } - - RootsTable& roots() { return roots_; } - const RootsTable& roots() const { return roots_; } - - ExternalReferenceTable* external_reference_table() { - return &external_reference_table_; - } - - Address* builtin_entry_table() { return builtin_entry_table_; } - Address* builtins() { return builtins_; } - private: // Static layout definition. // // Note: The location of fields within IsolateData is significant. The // closer they are to the value of kRootRegister (i.e.: isolate_root()), the // cheaper it is to access them. See also: https://crbug.com/993264. - // The recommend guideline is to put frequently-accessed fields close to the - // beginning of IsolateData. -#define FIELDS(V) \ - V(kEmbedderDataOffset, Internals::kNumIsolateDataSlots* kSystemPointerSize) \ - V(kFastCCallCallerFPOffset, kSystemPointerSize) \ - V(kFastCCallCallerPCOffset, kSystemPointerSize) \ - V(kFastApiCallTargetOffset, kSystemPointerSize) \ - V(kCageBaseOffset, kSystemPointerSize) \ - V(kLongTaskStatsCounterOffset, kSizetSize) \ - V(kStackGuardOffset, StackGuard::kSizeInBytes) \ - V(kRootsTableOffset, RootsTable::kEntriesCount* kSystemPointerSize) \ - V(kExternalReferenceTableOffset, ExternalReferenceTable::kSizeInBytes) \ - V(kThreadLocalTopOffset, ThreadLocalTop::kSizeInBytes) \ - V(kBuiltinEntryTableOffset, Builtins::kBuiltinCount* kSystemPointerSize) \ - V(kBuiltinsTableOffset, Builtins::kBuiltinCount* kSystemPointerSize) \ - FIELDS_HEAP_SANDBOX(V) \ - V(kStackIsIterableOffset, kUInt8Size) \ - /* This padding aligns IsolateData size by 8 bytes. */ \ - V(kPaddingOffset, \ - 8 + RoundUp<8>(static_cast(kPaddingOffset)) - kPaddingOffset) \ - /* Total size. */ \ + // The recommended guideline is to put frequently-accessed fields close to + // the beginning of IsolateData. +#define FIELDS(V) \ + ISOLATE_DATA_FIELDS(V) \ + /* This padding aligns IsolateData size by 8 bytes. */ \ + V(kPaddingOffset, \ + 8 + RoundUp<8>(static_cast(kPaddingOffset)) - kPaddingOffset) \ + /* Total size. */ \ V(kSize, 0) -#ifdef V8_HEAP_SANDBOX -#define FIELDS_HEAP_SANDBOX(V) \ - V(kExternalPointerTableOffset, kSystemPointerSize * 3) -#else -#define FIELDS_HEAP_SANDBOX(V) -#endif // V8_HEAP_SANDBOX - DEFINE_FIELD_OFFSET_CONSTANTS(0, FIELDS) #undef FIELDS + const Address cage_base_; + + // Fields related to the system and JS stack. In particular, this contains + // the stack limit used by stack checks in generated code. + StackGuard stack_guard_; + + // Tier 0 tables. See also builtin_entry_table_ and builtin_table_. + Address builtin_tier0_entry_table_[Builtins::kBuiltinTier0Count] = {}; + Address builtin_tier0_table_[Builtins::kBuiltinTier0Count] = {}; + // These fields are accessed through the API, offsets must be kept in sync - // with v8::internal::Internals (in include/v8-internal.h) constants. - // The layout consitency is verified in Isolate::CheckIsolateLayout() using + // with v8::internal::Internals (in include/v8-internal.h) constants. The + // layout consistency is verified in Isolate::CheckIsolateLayout() using // runtime checks. void* embedder_data_[Internals::kNumIsolateDataSlots] = {}; @@ -196,33 +176,30 @@ class IsolateData final { // the sampling CPU profiler can iterate the stack during such calls. These // are stored on IsolateData so that they can be stored to with only one move // instruction in compiled code. + // + // The FP and PC that are saved right before TurboAssembler::CallCFunction. Address fast_c_call_caller_fp_ = kNullAddress; Address fast_c_call_caller_pc_ = kNullAddress; + // The address of the fast API callback right before it's executed from + // generated code. Address fast_api_call_target_ = kNullAddress; - Address cage_base_ = kNullAddress; - // Used for implementation of LongTaskStats. Counts the number of potential // long tasks. size_t long_task_stats_counter_ = 0; - // Fields related to the system and JS stack. In particular, this contains - // the stack limit used by stack checks in generated code. - StackGuard stack_guard_; - - RootsTable roots_; - + RootsTable roots_table_; ExternalReferenceTable external_reference_table_; ThreadLocalTop thread_local_top_; - // The entry points for all builtins. This corresponds to + // The entry points for builtins. This corresponds to // Code::InstructionStart() for each Code object in the builtins table below. // The entry table is in IsolateData for easy access through kRootRegister. Address builtin_entry_table_[Builtins::kBuiltinCount] = {}; // The entries in this array are tagged pointers to Code objects. - Address builtins_[Builtins::kBuiltinCount] = {}; + Address builtin_table_[Builtins::kBuiltinCount] = {}; // Table containing pointers to external objects. #ifdef V8_HEAP_SANDBOX @@ -259,31 +236,16 @@ void IsolateData::AssertPredictableLayout() { STATIC_ASSERT(std::is_standard_layout::value); STATIC_ASSERT(std::is_standard_layout::value); STATIC_ASSERT(std::is_standard_layout::value); - STATIC_ASSERT(offsetof(IsolateData, roots_) == kRootsTableOffset); - STATIC_ASSERT(offsetof(IsolateData, external_reference_table_) == - kExternalReferenceTableOffset); - STATIC_ASSERT(offsetof(IsolateData, thread_local_top_) == - kThreadLocalTopOffset); - STATIC_ASSERT(offsetof(IsolateData, builtins_) == kBuiltinsTableOffset); - STATIC_ASSERT(offsetof(IsolateData, fast_c_call_caller_fp_) == - kFastCCallCallerFPOffset); - STATIC_ASSERT(offsetof(IsolateData, fast_c_call_caller_pc_) == - kFastCCallCallerPCOffset); - STATIC_ASSERT(offsetof(IsolateData, fast_api_call_target_) == - kFastApiCallTargetOffset); - STATIC_ASSERT(offsetof(IsolateData, cage_base_) == kCageBaseOffset); - STATIC_ASSERT(offsetof(IsolateData, long_task_stats_counter_) == - kLongTaskStatsCounterOffset); - STATIC_ASSERT(offsetof(IsolateData, stack_guard_) == kStackGuardOffset); -#ifdef V8_HEAP_SANDBOX - STATIC_ASSERT(offsetof(IsolateData, external_pointer_table_) == - kExternalPointerTableOffset); -#endif - STATIC_ASSERT(offsetof(IsolateData, stack_is_iterable_) == - kStackIsIterableOffset); +#define V(Offset, Size, Name) \ + STATIC_ASSERT(offsetof(IsolateData, Name##_) == Offset); + ISOLATE_DATA_FIELDS(V) +#undef V STATIC_ASSERT(sizeof(IsolateData) == IsolateData::kSize); } +#undef ISOLATE_DATA_FIELDS_HEAP_SANDBOX +#undef ISOLATE_DATA_FIELDS + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/execution/isolate.cc b/deps/v8/src/execution/isolate.cc index c630cb73fa1440..b1b85e5bab54bd 100644 --- a/deps/v8/src/execution/isolate.cc +++ b/deps/v8/src/execution/isolate.cc @@ -2673,10 +2673,10 @@ void Isolate::ReleaseSharedPtrs() { } } -bool Isolate::IsBuiltinsTableHandleLocation(Address* handle_location) { +bool Isolate::IsBuiltinTableHandleLocation(Address* handle_location) { FullObjectSlot location(handle_location); - FullObjectSlot first_root(builtins_table()); - FullObjectSlot last_root(builtins_table() + Builtins::kBuiltinCount); + FullObjectSlot first_root(builtin_table()); + FullObjectSlot last_root(builtin_table() + Builtins::kBuiltinCount); if (location >= last_root) return false; if (location < first_root) return false; return true; @@ -3047,9 +3047,15 @@ void Isolate::CheckIsolateLayout() { Internals::kIsolateLongTaskStatsCounterOffset); CHECK_EQ(static_cast(OFFSET_OF(Isolate, isolate_data_.stack_guard_)), Internals::kIsolateStackGuardOffset); - CHECK_EQ(static_cast(OFFSET_OF(Isolate, isolate_data_.roots_)), + CHECK_EQ(static_cast(OFFSET_OF(Isolate, isolate_data_.roots_table_)), Internals::kIsolateRootsOffset); + STATIC_ASSERT(Internals::kStackGuardSize == sizeof(StackGuard)); + STATIC_ASSERT(Internals::kBuiltinTier0TableSize == + Builtins::kBuiltinTier0Count * kSystemPointerSize); + STATIC_ASSERT(Internals::kBuiltinTier0EntryTableSize == + Builtins::kBuiltinTier0Count * kSystemPointerSize); + #ifdef V8_HEAP_SANDBOX CHECK_EQ(static_cast(OFFSET_OF(ExternalPointerTable, buffer_)), Internals::kExternalPointerTableBufferOffset); @@ -3748,7 +3754,7 @@ bool Isolate::Init(SnapshotData* startup_snapshot_data, delete setup_delegate_; setup_delegate_ = nullptr; - Builtins::InitializeBuiltinEntryTable(this); + Builtins::InitializeIsolateDataTables(this); Builtins::EmitCodeCreateEvents(this); #ifdef DEBUG @@ -4258,12 +4264,8 @@ MaybeHandle Isolate::RunHostImportModuleDynamicallyCallback( MaybeHandle maybe_import_assertions_argument) { v8::Local api_context = v8::Utils::ToLocal(Handle(native_context())); - DCHECK(host_import_module_dynamically_callback_ == nullptr || - host_import_module_dynamically_with_import_assertions_callback_ == - nullptr); - if (host_import_module_dynamically_callback_ == nullptr && - host_import_module_dynamically_with_import_assertions_callback_ == - nullptr) { + if (host_import_module_dynamically_with_import_assertions_callback_ == + nullptr) { Handle exception = factory()->NewError(error_function(), MessageTemplate::kUnsupported); return NewRejectedPromise(this, api_context, exception); @@ -4279,34 +4281,21 @@ MaybeHandle Isolate::RunHostImportModuleDynamicallyCallback( DCHECK(!has_pending_exception()); v8::Local promise; - - if (host_import_module_dynamically_with_import_assertions_callback_) { - Handle import_assertions_array; - if (GetImportAssertionsFromArgument(maybe_import_assertions_argument) - .ToHandle(&import_assertions_array)) { - ASSIGN_RETURN_ON_SCHEDULED_EXCEPTION_VALUE( - this, promise, - host_import_module_dynamically_with_import_assertions_callback_( - api_context, v8::Utils::ScriptOrModuleToLocal(referrer), - v8::Utils::ToLocal(specifier_str), - ToApiHandle(import_assertions_array)), - MaybeHandle()); - return v8::Utils::OpenHandle(*promise); - } else { - Handle exception(pending_exception(), this); - clear_pending_exception(); - return NewRejectedPromise(this, api_context, exception); - } - - } else { - DCHECK_NOT_NULL(host_import_module_dynamically_callback_); + Handle import_assertions_array; + if (GetImportAssertionsFromArgument(maybe_import_assertions_argument) + .ToHandle(&import_assertions_array)) { ASSIGN_RETURN_ON_SCHEDULED_EXCEPTION_VALUE( this, promise, - host_import_module_dynamically_callback_( + host_import_module_dynamically_with_import_assertions_callback_( api_context, v8::Utils::ScriptOrModuleToLocal(referrer), - v8::Utils::ToLocal(specifier_str)), + v8::Utils::ToLocal(specifier_str), + ToApiHandle(import_assertions_array)), MaybeHandle()); return v8::Utils::OpenHandle(*promise); + } else { + Handle exception(pending_exception(), this); + clear_pending_exception(); + return NewRejectedPromise(this, api_context, exception); } } @@ -4397,11 +4386,6 @@ MaybeHandle Isolate::GetImportAssertionsFromArgument( void Isolate::ClearKeptObjects() { heap()->ClearKeptObjects(); } -void Isolate::SetHostImportModuleDynamicallyCallback( - DeprecatedHostImportModuleDynamicallyCallback callback) { - host_import_module_dynamically_callback_ = callback; -} - void Isolate::SetHostImportModuleDynamicallyCallback( HostImportModuleDynamicallyWithImportAssertionsCallback callback) { host_import_module_dynamically_with_import_assertions_callback_ = callback; diff --git a/deps/v8/src/execution/isolate.h b/deps/v8/src/execution/isolate.h index e7908eac6aab00..6233d56906aa59 100644 --- a/deps/v8/src/execution/isolate.h +++ b/deps/v8/src/execution/isolate.h @@ -1123,9 +1123,9 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory { } Address* builtin_entry_table() { return isolate_data_.builtin_entry_table(); } - V8_INLINE Address* builtins_table() { return isolate_data_.builtins(); } + V8_INLINE Address* builtin_table() { return isolate_data_.builtin_table(); } - bool IsBuiltinsTableHandleLocation(Address* handle_location); + bool IsBuiltinTableHandleLocation(Address* handle_location); StubCache* load_stub_cache() const { return load_stub_cache_; } StubCache* store_stub_cache() const { return store_stub_cache_; } @@ -1644,18 +1644,6 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory { void ClearKeptObjects(); - // While deprecating v8::HostImportModuleDynamicallyCallback in v8.h we still - // need to support the version of the API that uses it, but we can't directly - // reference the deprecated version because of the enusing build warnings. So, - // we declare this matching type for temporary internal use. - // TODO(v8:10958) Delete this declaration and all references to it once - // v8::HostImportModuleDynamicallyCallback is removed. - typedef MaybeLocal (*DeprecatedHostImportModuleDynamicallyCallback)( - v8::Local context, v8::Local referrer, - v8::Local specifier); - - void SetHostImportModuleDynamicallyCallback( - DeprecatedHostImportModuleDynamicallyCallback callback); void SetHostImportModuleDynamicallyCallback( HostImportModuleDynamicallyWithImportAssertionsCallback callback); MaybeHandle RunHostImportModuleDynamicallyCallback( @@ -2022,8 +2010,6 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory { v8::Isolate::AtomicsWaitCallback atomics_wait_callback_ = nullptr; void* atomics_wait_callback_data_ = nullptr; PromiseHook promise_hook_ = nullptr; - DeprecatedHostImportModuleDynamicallyCallback - host_import_module_dynamically_callback_ = nullptr; HostImportModuleDynamicallyWithImportAssertionsCallback host_import_module_dynamically_with_import_assertions_callback_ = nullptr; std::atomic code_coverage_mode_{ diff --git a/deps/v8/src/handles/handles.cc b/deps/v8/src/handles/handles.cc index 392b1f8153889e..2503121e978106 100644 --- a/deps/v8/src/handles/handles.cc +++ b/deps/v8/src/handles/handles.cc @@ -43,7 +43,7 @@ bool HandleBase::IsDereferenceAllowed() const { RootsTable::IsImmortalImmovable(root_index)) { return true; } - if (isolate->IsBuiltinsTableHandleLocation(location_)) return true; + if (isolate->IsBuiltinTableHandleLocation(location_)) return true; if (!AllowHandleDereference::IsAllowed()) return false; LocalHeap* local_heap = isolate->CurrentLocalHeap(); diff --git a/deps/v8/src/heap/heap.cc b/deps/v8/src/heap/heap.cc index 0d0c4935a39fec..fa009bac9f3354 100644 --- a/deps/v8/src/heap/heap.cc +++ b/deps/v8/src/heap/heap.cc @@ -4653,21 +4653,29 @@ void Heap::ZapCodeObject(Address start_address, int size_in_bytes) { Code Heap::builtin(Builtin builtin) { DCHECK(Builtins::IsBuiltinId(builtin)); return Code::cast( - Object(isolate()->builtins_table()[static_cast(builtin)])); + Object(isolate()->builtin_table()[static_cast(builtin)])); } Address Heap::builtin_address(Builtin builtin) { + const int index = Builtins::ToInt(builtin); + DCHECK(Builtins::IsBuiltinId(builtin) || index == Builtins::kBuiltinCount); + // Note: Must return an address within the full builtin_table for + // IterateBuiltins to work. + return reinterpret_cast
(&isolate()->builtin_table()[index]); +} + +Address Heap::builtin_tier0_address(Builtin builtin) { const int index = static_cast(builtin); DCHECK(Builtins::IsBuiltinId(builtin) || index == Builtins::kBuiltinCount); - return reinterpret_cast
(&isolate()->builtins_table()[index]); + return reinterpret_cast
( + &isolate()->isolate_data()->builtin_tier0_table()[index]); } void Heap::set_builtin(Builtin builtin, Code code) { DCHECK(Builtins::IsBuiltinId(builtin)); DCHECK(Internals::HasHeapObjectTag(code.ptr())); - // The given builtin may be completely uninitialized thus we cannot check its - // type here. - isolate()->builtins_table()[static_cast(builtin)] = code.ptr(); + // The given builtin may be uninitialized thus we cannot check its type here. + isolate()->builtin_table()[Builtins::ToInt(builtin)] = code.ptr(); } void Heap::IterateWeakRoots(RootVisitor* v, base::EnumSet options) { @@ -4898,6 +4906,12 @@ void Heap::IterateBuiltins(RootVisitor* v) { FullObjectSlot(builtin_address(builtin))); } + for (Builtin builtin = Builtins::kFirst; builtin <= Builtins::kLastTier0; + ++builtin) { + v->VisitRootPointer(Root::kBuiltins, Builtins::name(builtin), + FullObjectSlot(builtin_tier0_address(builtin))); + } + // The entry table doesn't need to be updated since all builtins are embedded. STATIC_ASSERT(Builtins::AllBuiltinsAreIsolateIndependent()); } diff --git a/deps/v8/src/heap/heap.h b/deps/v8/src/heap/heap.h index e2e6316ef5a0ad..1a4ce1aaefc53d 100644 --- a/deps/v8/src/heap/heap.h +++ b/deps/v8/src/heap/heap.h @@ -1053,6 +1053,7 @@ class Heap { V8_EXPORT_PRIVATE Code builtin(Builtin builtin); Address builtin_address(Builtin builtin); + Address builtin_tier0_address(Builtin builtin); void set_builtin(Builtin builtin, Code code); // =========================================================================== diff --git a/deps/v8/src/utils/allocation.cc b/deps/v8/src/utils/allocation.cc index 6f6225797a6d9f..349a79c3856ea1 100644 --- a/deps/v8/src/utils/allocation.cc +++ b/deps/v8/src/utils/allocation.cc @@ -143,10 +143,10 @@ char* StrNDup(const char* str, size_t n) { return result; } -void* AllocWithRetry(size_t size) { +void* AllocWithRetry(size_t size, MallocFn malloc_fn) { void* result = nullptr; for (int i = 0; i < kAllocationTries; ++i) { - result = base::Malloc(size); + result = malloc_fn(size); if (result != nullptr) break; if (!OnCriticalMemoryPressure(size)) break; } diff --git a/deps/v8/src/utils/allocation.h b/deps/v8/src/utils/allocation.h index 93499cc5e162a3..e28266ad433c68 100644 --- a/deps/v8/src/utils/allocation.h +++ b/deps/v8/src/utils/allocation.h @@ -90,9 +90,11 @@ class FreeStoreAllocationPolicy { } }; +using MallocFn = void* (*)(size_t); + // Performs a malloc, with retry logic on failure. Returns nullptr on failure. // Call free to release memory allocated with this function. -void* AllocWithRetry(size_t size); +void* AllocWithRetry(size_t size, MallocFn = base::Malloc); V8_EXPORT_PRIVATE void* AlignedAlloc(size_t size, size_t alignment); V8_EXPORT_PRIVATE void AlignedFree(void* ptr); diff --git a/deps/v8/src/utils/utils.h b/deps/v8/src/utils/utils.h index 5238062e05508b..005e1c4ad4e13c 100644 --- a/deps/v8/src/utils/utils.h +++ b/deps/v8/src/utils/utils.h @@ -217,7 +217,8 @@ inline T RoundingAverageUnsigned(T a, T b) { // // DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, MAP_FIELDS) // -#define DEFINE_ONE_FIELD_OFFSET(Name, Size) Name, Name##End = Name + (Size)-1, +#define DEFINE_ONE_FIELD_OFFSET(Name, Size, ...) \ + Name, Name##End = Name + (Size)-1, #define DEFINE_FIELD_OFFSET_CONSTANTS(StartOffset, LIST_MACRO) \ enum { \ diff --git a/deps/v8/src/zone/accounting-allocator.cc b/deps/v8/src/zone/accounting-allocator.cc index baa70162fd925a..f6f72d461651c0 100644 --- a/deps/v8/src/zone/accounting-allocator.cc +++ b/deps/v8/src/zone/accounting-allocator.cc @@ -65,7 +65,11 @@ std::unique_ptr CreateBoundedAllocator( } // namespace -AccountingAllocator::AccountingAllocator() { +AccountingAllocator::AccountingAllocator() + : zone_backing_malloc_( + V8::GetCurrentPlatform()->GetZoneBackingAllocator()->GetMallocFn()), + zone_backing_free_( + V8::GetCurrentPlatform()->GetZoneBackingAllocator()->GetFreeFn()) { if (COMPRESS_ZONES_BOOL) { v8::PageAllocator* platform_page_allocator = GetPlatformPageAllocator(); VirtualMemory memory = ReserveAddressSpace(platform_page_allocator); @@ -86,7 +90,7 @@ Segment* AccountingAllocator::AllocateSegment(size_t bytes, kZonePageSize, PageAllocator::kReadWrite); } else { - memory = AllocWithRetry(bytes); + memory = AllocWithRetry(bytes, zone_backing_malloc_); } if (memory == nullptr) return nullptr; @@ -110,7 +114,7 @@ void AccountingAllocator::ReturnSegment(Segment* segment, if (COMPRESS_ZONES_BOOL && supports_compression) { CHECK(FreePages(bounded_page_allocator_.get(), segment, segment_size)); } else { - base::Free(segment); + zone_backing_free_(segment); } } diff --git a/deps/v8/src/zone/accounting-allocator.h b/deps/v8/src/zone/accounting-allocator.h index 88a0c7559710a0..7fdc86da7d255e 100644 --- a/deps/v8/src/zone/accounting-allocator.h +++ b/deps/v8/src/zone/accounting-allocator.h @@ -8,6 +8,7 @@ #include #include +#include "include/v8-platform.h" #include "src/base/macros.h" #include "src/logging/tracing-flags.h" @@ -71,6 +72,9 @@ class V8_EXPORT_PRIVATE AccountingAllocator { std::unique_ptr reserved_area_; std::unique_ptr bounded_page_allocator_; + + ZoneBackingAllocator::MallocFn zone_backing_malloc_ = nullptr; + ZoneBackingAllocator::FreeFn zone_backing_free_ = nullptr; }; } // namespace internal