mirror of
https://github.com/nodejs/node.git
synced 2026-10-14 10:26:26 -04:00
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 <duhamelantoine1995@gmail.com> Reviewed-By: Beth Griggs <bgriggs@redhat.com>
This commit is contained in:
42 files changed
+458
-385
No files matched your search
+1
-1
@@ -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 #####
|
||||
|
||||
|
||||
Vendored
-25
@@ -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<Promise> (*)(Local<Context> context,
|
||||
Local<ScriptOrModule> referrer,
|
||||
Local<String> specifier);
|
||||
|
||||
// --- Exceptions ---
|
||||
|
||||
using FatalErrorCallback = void (*)(const char* location, const char* message);
|
||||
|
||||
Vendored
+15
-8
@@ -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 =
|
||||
|
||||
Vendored
-10
@@ -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.
|
||||
|
||||
Vendored
+20
@@ -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
|
||||
|
||||
Vendored
-6
@@ -8544,12 +8544,6 @@ void Isolate::SetAbortOnUncaughtExceptionCallback(
|
||||
isolate->SetAbortOnUncaughtExceptionCallback(callback);
|
||||
}
|
||||
|
||||
void Isolate::SetHostImportModuleDynamicallyCallback(
|
||||
i::Isolate::DeprecatedHostImportModuleDynamicallyCallback callback) {
|
||||
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
|
||||
isolate->SetHostImportModuleDynamicallyCallback(callback);
|
||||
}
|
||||
|
||||
void Isolate::SetHostImportModuleDynamicallyCallback(
|
||||
HostImportModuleDynamicallyWithImportAssertionsCallback callback) {
|
||||
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
|
||||
|
||||
+50
-21
@@ -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) \
|
||||
|
||||
Vendored
+25
-19
@@ -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<int>(builtin));
|
||||
ToInt(builtin));
|
||||
}
|
||||
|
||||
Builtin Builtins::GetBuiltinFromBytecodeOffset(BytecodeOffset id) {
|
||||
@@ -182,7 +182,7 @@ Handle<Code> Builtins::code_handle(Builtin builtin) {
|
||||
// static
|
||||
int Builtins::GetStackParameterCount(Builtin builtin) {
|
||||
DCHECK(Builtins::KindOf(builtin) == TFJ);
|
||||
return builtin_metadata[static_cast<int>(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<int>(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<int>(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<int>(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<int>(Builtin::kFirstBytecodeHandler); i++) {
|
||||
for (; i < ToInt(Builtin::kFirstBytecodeHandler); i++) {
|
||||
Handle<AbstractCode> code(AbstractCode::cast(Object(builtins[i])), isolate);
|
||||
PROFILE(isolate, CodeCreateEvent(CodeEventListener::BUILTIN_TAG, code,
|
||||
Builtins::name(FromInt(i))));
|
||||
@@ -420,7 +426,7 @@ Handle<ByteArray> Builtins::GenerateOffHeapTrampolineRelocInfo(
|
||||
|
||||
Builtins::Kind Builtins::KindOf(Builtin builtin) {
|
||||
DCHECK(IsBuiltinId(builtin));
|
||||
return builtin_metadata[static_cast<int>(builtin)].kind;
|
||||
return builtin_metadata[ToInt(builtin)].kind;
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
Vendored
+12
-3
@@ -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<Builtin>(0);
|
||||
static constexpr Builtin kLast = static_cast<Builtin>(kBuiltinCount - 1);
|
||||
static constexpr Builtin kLastTier0 =
|
||||
static_cast<Builtin>(kBuiltinTier0Count - 1);
|
||||
|
||||
static constexpr int kFirstWideBytecodeHandler =
|
||||
static_cast<int>(Builtin::kFirstBytecodeHandler) +
|
||||
@@ -96,11 +100,18 @@ class Builtins {
|
||||
return static_cast<uint32_t>(maybe_id) <
|
||||
static_cast<uint32_t>(kBuiltinCount);
|
||||
}
|
||||
static constexpr bool IsTier0(Builtin builtin) {
|
||||
return builtin <= kLastTier0 && IsBuiltinId(builtin);
|
||||
}
|
||||
|
||||
static constexpr Builtin FromInt(int id) {
|
||||
DCHECK(IsBuiltinId(id));
|
||||
return static_cast<Builtin>(id);
|
||||
}
|
||||
static constexpr int ToInt(Builtin id) {
|
||||
DCHECK(IsBuiltinId(id));
|
||||
return static_cast<int>(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);
|
||||
|
||||
+7
-1
@@ -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) ||
|
||||
|
||||
+14
-5
@@ -182,7 +182,7 @@ void TurboAssembler::Jump(Handle<Code> 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> 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(); }
|
||||
|
||||
+1
-1
@@ -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) {
|
||||
|
||||
+1
-2
@@ -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,
|
||||
|
||||
+3
-3
@@ -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)
|
||||
|
||||
+2
-2
@@ -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)
|
||||
|
||||
+2
-2
@@ -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)
|
||||
|
||||
+23
-19
@@ -187,15 +187,14 @@ void TurboAssembler::Jump(Handle<Code> 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<int>(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> 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> 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<int>(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> 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> code, RelocInfo::Mode rmode,
|
||||
Call(static_cast<Address>(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)
|
||||
|
||||
@@ -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
|
||||
|
||||
+2
-2
@@ -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)
|
||||
|
||||
+18
-10
@@ -416,14 +416,14 @@ void TurboAssembler::Jump(Handle<Code> 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> 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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+1
-2
@@ -1915,8 +1915,7 @@ void TurboAssembler::Call(Handle<Code> 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) {
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
+13
@@ -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;
|
||||
|
||||
+13
-4
@@ -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;
|
||||
|
||||
+3
-3
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
+16
-3
@@ -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;
|
||||
|
||||
+16
-7
@@ -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<unsigned>(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<unsigned>(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<unsigned>(offset - kBuiltinsTableStart) <
|
||||
kBuiltinsTableSize) {
|
||||
uint32_t offset_in_builtins_table = (offset - kBuiltinsTableStart);
|
||||
} else if (static_cast<unsigned>(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<unsigned>(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()) {
|
||||
|
||||
Vendored
+2
-1
@@ -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<Address*>(
|
||||
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);
|
||||
|
||||
Vendored
+117
-155
@@ -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<Address>(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<int>(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;
|
||||
}
|
||||
|
||||
static constexpr int cage_base_offset() {
|
||||
return kCageBaseOffset - kIsolateRootBias;
|
||||
}
|
||||
|
||||
// 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;
|
||||
static constexpr int builtin_slot_offset(int builtin_index) {
|
||||
return BuiltinSlotOffset(Builtins::FromInt(builtin_index));
|
||||
}
|
||||
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 builtin table entry.
|
||||
static int builtin_slot_offset(Builtin id) {
|
||||
return builtins_table_offset() + static_cast<int>(id) * kSystemPointerSize;
|
||||
}
|
||||
#define V(Offset, Size, Name) \
|
||||
Address Name##_address() { return reinterpret_cast<Address>(&Name##_); }
|
||||
ISOLATE_DATA_FIELDS(V)
|
||||
#undef V
|
||||
|
||||
// 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_; }
|
||||
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_; }
|
||||
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_; }
|
||||
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_; }
|
||||
|
||||
// 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<Address>::value);
|
||||
Address start = reinterpret_cast<Address>(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<int>(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<int>(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<ThreadLocalTop>::value);
|
||||
STATIC_ASSERT(std::is_standard_layout<ExternalReferenceTable>::value);
|
||||
STATIC_ASSERT(std::is_standard_layout<IsolateData>::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
|
||||
|
||||
|
||||
Vendored
+23
-39
@@ -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<int>(OFFSET_OF(Isolate, isolate_data_.stack_guard_)),
|
||||
Internals::kIsolateStackGuardOffset);
|
||||
CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, isolate_data_.roots_)),
|
||||
CHECK_EQ(static_cast<int>(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<int>(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<JSPromise> Isolate::RunHostImportModuleDynamicallyCallback(
|
||||
MaybeHandle<Object> maybe_import_assertions_argument) {
|
||||
v8::Local<v8::Context> api_context =
|
||||
v8::Utils::ToLocal(Handle<Context>(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<Object> exception =
|
||||
factory()->NewError(error_function(), MessageTemplate::kUnsupported);
|
||||
return NewRejectedPromise(this, api_context, exception);
|
||||
@@ -4279,34 +4281,21 @@ MaybeHandle<JSPromise> Isolate::RunHostImportModuleDynamicallyCallback(
|
||||
DCHECK(!has_pending_exception());
|
||||
|
||||
v8::Local<v8::Promise> promise;
|
||||
|
||||
if (host_import_module_dynamically_with_import_assertions_callback_) {
|
||||
Handle<FixedArray> 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<v8::FixedArray>(import_assertions_array)),
|
||||
MaybeHandle<JSPromise>());
|
||||
return v8::Utils::OpenHandle(*promise);
|
||||
} else {
|
||||
Handle<Object> exception(pending_exception(), this);
|
||||
clear_pending_exception();
|
||||
return NewRejectedPromise(this, api_context, exception);
|
||||
}
|
||||
|
||||
} else {
|
||||
DCHECK_NOT_NULL(host_import_module_dynamically_callback_);
|
||||
Handle<FixedArray> 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<v8::FixedArray>(import_assertions_array)),
|
||||
MaybeHandle<JSPromise>());
|
||||
return v8::Utils::OpenHandle(*promise);
|
||||
} else {
|
||||
Handle<Object> exception(pending_exception(), this);
|
||||
clear_pending_exception();
|
||||
return NewRejectedPromise(this, api_context, exception);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4397,11 +4386,6 @@ MaybeHandle<FixedArray> 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;
|
||||
|
||||
Vendored
+2
-16
@@ -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<Promise> (*DeprecatedHostImportModuleDynamicallyCallback)(
|
||||
v8::Local<v8::Context> context, v8::Local<v8::ScriptOrModule> referrer,
|
||||
v8::Local<v8::String> specifier);
|
||||
|
||||
void SetHostImportModuleDynamicallyCallback(
|
||||
DeprecatedHostImportModuleDynamicallyCallback callback);
|
||||
void SetHostImportModuleDynamicallyCallback(
|
||||
HostImportModuleDynamicallyWithImportAssertionsCallback callback);
|
||||
MaybeHandle<JSPromise> 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<debug::CoverageMode> code_coverage_mode_{
|
||||
|
||||
Vendored
+1
-1
@@ -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();
|
||||
|
||||
Vendored
+19
-5
@@ -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<int>(builtin)]));
|
||||
Object(isolate()->builtin_table()[static_cast<int>(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<Address>(&isolate()->builtin_table()[index]);
|
||||
}
|
||||
|
||||
Address Heap::builtin_tier0_address(Builtin builtin) {
|
||||
const int index = static_cast<int>(builtin);
|
||||
DCHECK(Builtins::IsBuiltinId(builtin) || index == Builtins::kBuiltinCount);
|
||||
return reinterpret_cast<Address>(&isolate()->builtins_table()[index]);
|
||||
return reinterpret_cast<Address>(
|
||||
&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<int>(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<SkipRoot> 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());
|
||||
}
|
||||
|
||||
Vendored
+1
@@ -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);
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
Vendored
+2
-2
@@ -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;
|
||||
}
|
||||
|
||||
Vendored
+3
-1
@@ -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);
|
||||
|
||||
Vendored
+2
-1
@@ -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 { \
|
||||
|
||||
+7
-3
@@ -65,7 +65,11 @@ std::unique_ptr<v8::base::BoundedPageAllocator> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -8,6 +8,7 @@
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
|
||||
#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<VirtualMemory> reserved_area_;
|
||||
std::unique_ptr<base::BoundedPageAllocator> bounded_page_allocator_;
|
||||
|
||||
ZoneBackingAllocator::MallocFn zone_backing_malloc_ = nullptr;
|
||||
ZoneBackingAllocator::FreeFn zone_backing_free_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
Reference in new issue
Block a user