Reland "[heap] Make trampoline CodeDataContainers immutable and deduplicate them"
Fixed by6644f2b872
(https://chromium-review.googlesource.com/c/v8/v8/+/1605728) This is a reland of652e32f9f9
Original change's description: > [heap] Make trampoline CodeDataContainers immutable and deduplicate them > > Moves all trampoline CodeDataContainers to read-only space, making them > immutable. Containers with no 'kind specific flags' set or 'promise > rejection' flag are deduplicated by replacing them with the new canonical > CodeDataContainers roots. > > This saves around 36KB from the snapshot. > > RO_SPACE NEW_SPACE OLD_SPACE CODE_SPACE MAP_SPACE LO_SPACE > old 32048 0 225944 149280 20240 0 > new 32120 0 189344 149280 20240 0 > > Bug: v8:7464 > Change-Id: Iedd538a86311ef501cd88c90ec75e1308195762f > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1601257 > Commit-Queue: Maciej Goszczycki <goszczycki@google.com> > Reviewed-by: Ulan Degenbaev <ulan@chromium.org> > Reviewed-by: Dan Elphick <delphick@chromium.org> > Cr-Commit-Position: refs/heads/master@{#61378} Bug: v8:7464 Change-Id: Ib98577d7d6c8c1205c94bf8c57d9cb38f51fdad3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1609539 Commit-Queue: Maciej Goszczycki <goszczycki@google.com> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Cr-Commit-Position: refs/heads/master@{#61451}
This commit is contained in:
parent
d08eb7364f
commit
f22bd828e5
@ -291,8 +291,8 @@ constexpr int OffHeapTrampolineGenerator::kBufferSize;
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
Handle<Code> Builtins::GenerateOffHeapTrampolineFor(Isolate* isolate,
|
||||
Address off_heap_entry) {
|
||||
Handle<Code> Builtins::GenerateOffHeapTrampolineFor(
|
||||
Isolate* isolate, Address off_heap_entry, int32_t kind_specfic_flags) {
|
||||
DCHECK_NOT_NULL(isolate->embedded_blob());
|
||||
DCHECK_NE(0, isolate->embedded_blob_size());
|
||||
|
||||
@ -301,6 +301,7 @@ Handle<Code> Builtins::GenerateOffHeapTrampolineFor(Isolate* isolate,
|
||||
|
||||
return Factory::CodeBuilder(isolate, desc, Code::BUILTIN)
|
||||
.set_self_reference(generator.CodeObject())
|
||||
.set_read_only_data_container(kind_specfic_flags)
|
||||
.Build();
|
||||
}
|
||||
|
||||
|
@ -172,7 +172,8 @@ class Builtins {
|
||||
// The result should not be used directly, but only from the related Factory
|
||||
// function.
|
||||
static Handle<Code> GenerateOffHeapTrampolineFor(Isolate* isolate,
|
||||
Address off_heap_entry);
|
||||
Address off_heap_entry,
|
||||
int32_t kind_specific_flags);
|
||||
|
||||
// Generate the RelocInfo ByteArray that would be generated for an offheap
|
||||
// trampoline.
|
||||
|
@ -86,7 +86,29 @@ MaybeHandle<Code> Factory::CodeBuilder::BuildInternal(
|
||||
// Allocate objects needed for code initialization.
|
||||
Handle<ByteArray> reloc_info =
|
||||
factory->NewByteArray(code_desc_.reloc_size, AllocationType::kOld);
|
||||
Handle<CodeDataContainer> data_container = factory->NewCodeDataContainer(0);
|
||||
Handle<CodeDataContainer> data_container;
|
||||
|
||||
// Use a canonical off-heap trampoline CodeDataContainer if possible.
|
||||
const int32_t promise_rejection_flag =
|
||||
Code::IsPromiseRejectionField::encode(true);
|
||||
if (read_only_data_container_ &&
|
||||
(kind_specific_flags_ == 0 ||
|
||||
kind_specific_flags_ == promise_rejection_flag)) {
|
||||
const ReadOnlyRoots roots(isolate_);
|
||||
const auto canonical_code_data_container =
|
||||
kind_specific_flags_ == 0
|
||||
? roots.trampoline_trivial_code_data_container_handle()
|
||||
: roots.trampoline_promise_rejection_code_data_container_handle();
|
||||
DCHECK_EQ(canonical_code_data_container->kind_specific_flags(),
|
||||
kind_specific_flags_);
|
||||
data_container = canonical_code_data_container;
|
||||
} else {
|
||||
data_container = factory->NewCodeDataContainer(
|
||||
0, read_only_data_container_ ? AllocationType::kReadOnly
|
||||
: AllocationType::kOld);
|
||||
data_container->set_kind_specific_flags(kind_specific_flags_);
|
||||
}
|
||||
|
||||
Handle<Code> code;
|
||||
{
|
||||
int object_size = ComputeCodeObjectSize(code_desc_);
|
||||
@ -2684,10 +2706,10 @@ Handle<JSObject> Factory::NewExternal(void* value) {
|
||||
return external;
|
||||
}
|
||||
|
||||
Handle<CodeDataContainer> Factory::NewCodeDataContainer(int flags) {
|
||||
Handle<CodeDataContainer> Factory::NewCodeDataContainer(
|
||||
int flags, AllocationType allocation) {
|
||||
Handle<CodeDataContainer> data_container(
|
||||
CodeDataContainer::cast(
|
||||
New(code_data_container_map(), AllocationType::kOld)),
|
||||
CodeDataContainer::cast(New(code_data_container_map(), allocation)),
|
||||
isolate());
|
||||
data_container->set_next_code_link(*undefined_value(), SKIP_WRITE_BARRIER);
|
||||
data_container->set_kind_specific_flags(flags);
|
||||
@ -2701,12 +2723,14 @@ Handle<Code> Factory::NewOffHeapTrampolineFor(Handle<Code> code,
|
||||
CHECK_NE(0, isolate()->embedded_blob_size());
|
||||
CHECK(Builtins::IsIsolateIndependentBuiltin(*code));
|
||||
|
||||
Handle<Code> result =
|
||||
Builtins::GenerateOffHeapTrampolineFor(isolate(), off_heap_entry);
|
||||
Handle<Code> result = Builtins::GenerateOffHeapTrampolineFor(
|
||||
isolate(), off_heap_entry,
|
||||
code->code_data_container()->kind_specific_flags());
|
||||
// The CodeDataContainer should not be modified beyond this point since it's
|
||||
// now possibly canonicalized.
|
||||
|
||||
// The trampoline code object must inherit specific flags from the original
|
||||
// builtin (e.g. the safepoint-table offset). We set them manually here.
|
||||
|
||||
{
|
||||
MemoryChunk* chunk = MemoryChunk::FromHeapObject(*result);
|
||||
CodePageMemoryModificationScope code_allocation(chunk);
|
||||
@ -2714,8 +2738,6 @@ Handle<Code> Factory::NewOffHeapTrampolineFor(Handle<Code> code,
|
||||
const bool set_is_off_heap_trampoline = true;
|
||||
const int stack_slots =
|
||||
code->has_safepoint_info() ? code->stack_slots() : 0;
|
||||
result->code_data_container()->set_kind_specific_flags(
|
||||
code->code_data_container()->kind_specific_flags());
|
||||
result->initialize_flags(code->kind(), code->has_unwinding_info(),
|
||||
code->is_turbofanned(), stack_slots,
|
||||
set_is_off_heap_trampoline);
|
||||
@ -2745,8 +2767,8 @@ Handle<Code> Factory::NewOffHeapTrampolineFor(Handle<Code> code,
|
||||
}
|
||||
|
||||
Handle<Code> Factory::CopyCode(Handle<Code> code) {
|
||||
Handle<CodeDataContainer> data_container =
|
||||
NewCodeDataContainer(code->code_data_container()->kind_specific_flags());
|
||||
Handle<CodeDataContainer> data_container = NewCodeDataContainer(
|
||||
code->code_data_container()->kind_specific_flags(), AllocationType::kOld);
|
||||
|
||||
Heap* heap = isolate()->heap();
|
||||
Handle<Code> new_code;
|
||||
|
@ -793,7 +793,8 @@ class V8_EXPORT_PRIVATE Factory {
|
||||
Handle<JSObject> NewExternal(void* value);
|
||||
|
||||
// Creates a new CodeDataContainer for a Code object.
|
||||
Handle<CodeDataContainer> NewCodeDataContainer(int flags);
|
||||
Handle<CodeDataContainer> NewCodeDataContainer(int flags,
|
||||
AllocationType allocation);
|
||||
|
||||
// Allocates a new code object and initializes it as the trampoline to the
|
||||
// given off-heap entry point.
|
||||
@ -958,29 +959,44 @@ class V8_EXPORT_PRIVATE Factory {
|
||||
self_reference_ = self_reference;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CodeBuilder& set_builtin_index(int32_t builtin_index) {
|
||||
builtin_index_ = builtin_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CodeBuilder& set_source_position_table(Handle<ByteArray> table) {
|
||||
DCHECK(!table.is_null());
|
||||
source_position_table_ = table;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CodeBuilder& set_deoptimization_data(
|
||||
Handle<DeoptimizationData> deopt_data) {
|
||||
DCHECK(!deopt_data.is_null());
|
||||
deoptimization_data_ = deopt_data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CodeBuilder& set_immovable() {
|
||||
is_movable_ = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CodeBuilder& set_is_turbofanned() {
|
||||
is_turbofanned_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Indicates the CodeDataContainer should be allocated in read-only space.
|
||||
// As an optimization, if the kind-specific flags match that of a canonical
|
||||
// container, it will be used instead.
|
||||
CodeBuilder& set_read_only_data_container(int32_t flags) {
|
||||
read_only_data_container_ = true;
|
||||
kind_specific_flags_ = flags;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CodeBuilder& set_stack_slots(int stack_slots) {
|
||||
stack_slots_ = stack_slots;
|
||||
return *this;
|
||||
@ -995,9 +1011,11 @@ class V8_EXPORT_PRIVATE Factory {
|
||||
|
||||
MaybeHandle<Object> self_reference_;
|
||||
int32_t builtin_index_ = Builtins::kNoBuiltinId;
|
||||
int32_t kind_specific_flags_ = 0;
|
||||
Handle<ByteArray> source_position_table_;
|
||||
Handle<DeoptimizationData> deoptimization_data_ =
|
||||
DeoptimizationData::Empty(isolate_);
|
||||
bool read_only_data_container_ = false;
|
||||
bool is_movable_ = true;
|
||||
bool is_turbofanned_ = false;
|
||||
int stack_slots_ = 0;
|
||||
|
@ -939,9 +939,19 @@ void Heap::CreateInitialObjects() {
|
||||
|
||||
set_noscript_shared_function_infos(roots.empty_weak_array_list());
|
||||
|
||||
/* Canonical off-heap trampoline data */
|
||||
set_off_heap_trampoline_relocation_info(
|
||||
*Builtins::GenerateOffHeapTrampolineRelocInfo(isolate_));
|
||||
|
||||
set_trampoline_trivial_code_data_container(
|
||||
*isolate()->factory()->NewCodeDataContainer(0,
|
||||
AllocationType::kReadOnly));
|
||||
|
||||
set_trampoline_promise_rejection_code_data_container(
|
||||
*isolate()->factory()->NewCodeDataContainer(
|
||||
Code::IsPromiseRejectionField::encode(true),
|
||||
AllocationType::kReadOnly));
|
||||
|
||||
// Evaluate the hash values which will then be cached in the strings.
|
||||
isolate()->factory()->zero_string()->Hash();
|
||||
isolate()->factory()->one_string()->Hash();
|
||||
|
@ -216,9 +216,13 @@ class Symbol;
|
||||
V(HeapNumber, minus_infinity_value, MinusInfinityValue) \
|
||||
/* Marker for self-references during code-generation */ \
|
||||
V(HeapObject, self_reference_marker, SelfReferenceMarker) \
|
||||
/* Canonical trampoline RelocInfo */ \
|
||||
/* Canonical off-heap trampoline data */ \
|
||||
V(ByteArray, off_heap_trampoline_relocation_info, \
|
||||
OffHeapTrampolineRelocationInfo) \
|
||||
V(CodeDataContainer, trampoline_trivial_code_data_container, \
|
||||
TrampolineTrivialCodeDataContainer) \
|
||||
V(CodeDataContainer, trampoline_promise_rejection_code_data_container, \
|
||||
TrampolinePromiseRejectionCodeDataContainer) \
|
||||
/* Hash seed */ \
|
||||
V(ByteArray, hash_seed, HashSeed)
|
||||
|
||||
|
@ -306,49 +306,49 @@ KNOWN_MAPS = {
|
||||
("read_only_space", 0x026e9): (98, "EnumCacheMap"),
|
||||
("read_only_space", 0x02789): (115, "ArrayBoilerplateDescriptionMap"),
|
||||
("read_only_space", 0x02ad9): (101, "InterceptorInfoMap"),
|
||||
("read_only_space", 0x05269): (89, "AccessCheckInfoMap"),
|
||||
("read_only_space", 0x052b9): (90, "AccessorInfoMap"),
|
||||
("read_only_space", 0x05309): (91, "AccessorPairMap"),
|
||||
("read_only_space", 0x05359): (92, "AliasedArgumentsEntryMap"),
|
||||
("read_only_space", 0x053a9): (93, "AllocationMementoMap"),
|
||||
("read_only_space", 0x053f9): (94, "AsmWasmDataMap"),
|
||||
("read_only_space", 0x05449): (95, "AsyncGeneratorRequestMap"),
|
||||
("read_only_space", 0x05499): (96, "ClassPositionsMap"),
|
||||
("read_only_space", 0x054e9): (97, "DebugInfoMap"),
|
||||
("read_only_space", 0x05539): (99, "FunctionTemplateInfoMap"),
|
||||
("read_only_space", 0x05589): (100, "FunctionTemplateRareDataMap"),
|
||||
("read_only_space", 0x055d9): (102, "InterpreterDataMap"),
|
||||
("read_only_space", 0x05629): (103, "ModuleInfoEntryMap"),
|
||||
("read_only_space", 0x05679): (104, "ModuleMap"),
|
||||
("read_only_space", 0x056c9): (105, "ObjectTemplateInfoMap"),
|
||||
("read_only_space", 0x05719): (106, "PromiseCapabilityMap"),
|
||||
("read_only_space", 0x05769): (107, "PromiseReactionMap"),
|
||||
("read_only_space", 0x057b9): (108, "PrototypeInfoMap"),
|
||||
("read_only_space", 0x05809): (109, "ScriptMap"),
|
||||
("read_only_space", 0x05859): (110, "SourcePositionTableWithFrameCacheMap"),
|
||||
("read_only_space", 0x058a9): (111, "StackFrameInfoMap"),
|
||||
("read_only_space", 0x058f9): (112, "StackTraceFrameMap"),
|
||||
("read_only_space", 0x05949): (113, "Tuple2Map"),
|
||||
("read_only_space", 0x05999): (114, "Tuple3Map"),
|
||||
("read_only_space", 0x059e9): (116, "WasmCapiFunctionDataMap"),
|
||||
("read_only_space", 0x05a39): (117, "WasmDebugInfoMap"),
|
||||
("read_only_space", 0x05a89): (118, "WasmExceptionTagMap"),
|
||||
("read_only_space", 0x05ad9): (119, "WasmExportedFunctionDataMap"),
|
||||
("read_only_space", 0x05b29): (120, "CallableTaskMap"),
|
||||
("read_only_space", 0x05b79): (121, "CallbackTaskMap"),
|
||||
("read_only_space", 0x05bc9): (122, "PromiseFulfillReactionJobTaskMap"),
|
||||
("read_only_space", 0x05c19): (123, "PromiseRejectReactionJobTaskMap"),
|
||||
("read_only_space", 0x05c69): (124, "PromiseResolveThenableJobTaskMap"),
|
||||
("read_only_space", 0x05cb9): (125, "FinalizationGroupCleanupJobTaskMap"),
|
||||
("read_only_space", 0x05d09): (126, "AllocationSiteWithWeakNextMap"),
|
||||
("read_only_space", 0x05d59): (126, "AllocationSiteWithoutWeakNextMap"),
|
||||
("read_only_space", 0x05da9): (161, "LoadHandler1Map"),
|
||||
("read_only_space", 0x05df9): (161, "LoadHandler2Map"),
|
||||
("read_only_space", 0x05e49): (161, "LoadHandler3Map"),
|
||||
("read_only_space", 0x05e99): (169, "StoreHandler0Map"),
|
||||
("read_only_space", 0x05ee9): (169, "StoreHandler1Map"),
|
||||
("read_only_space", 0x05f39): (169, "StoreHandler2Map"),
|
||||
("read_only_space", 0x05f89): (169, "StoreHandler3Map"),
|
||||
("read_only_space", 0x05299): (89, "AccessCheckInfoMap"),
|
||||
("read_only_space", 0x052e9): (90, "AccessorInfoMap"),
|
||||
("read_only_space", 0x05339): (91, "AccessorPairMap"),
|
||||
("read_only_space", 0x05389): (92, "AliasedArgumentsEntryMap"),
|
||||
("read_only_space", 0x053d9): (93, "AllocationMementoMap"),
|
||||
("read_only_space", 0x05429): (94, "AsmWasmDataMap"),
|
||||
("read_only_space", 0x05479): (95, "AsyncGeneratorRequestMap"),
|
||||
("read_only_space", 0x054c9): (96, "ClassPositionsMap"),
|
||||
("read_only_space", 0x05519): (97, "DebugInfoMap"),
|
||||
("read_only_space", 0x05569): (99, "FunctionTemplateInfoMap"),
|
||||
("read_only_space", 0x055b9): (100, "FunctionTemplateRareDataMap"),
|
||||
("read_only_space", 0x05609): (102, "InterpreterDataMap"),
|
||||
("read_only_space", 0x05659): (103, "ModuleInfoEntryMap"),
|
||||
("read_only_space", 0x056a9): (104, "ModuleMap"),
|
||||
("read_only_space", 0x056f9): (105, "ObjectTemplateInfoMap"),
|
||||
("read_only_space", 0x05749): (106, "PromiseCapabilityMap"),
|
||||
("read_only_space", 0x05799): (107, "PromiseReactionMap"),
|
||||
("read_only_space", 0x057e9): (108, "PrototypeInfoMap"),
|
||||
("read_only_space", 0x05839): (109, "ScriptMap"),
|
||||
("read_only_space", 0x05889): (110, "SourcePositionTableWithFrameCacheMap"),
|
||||
("read_only_space", 0x058d9): (111, "StackFrameInfoMap"),
|
||||
("read_only_space", 0x05929): (112, "StackTraceFrameMap"),
|
||||
("read_only_space", 0x05979): (113, "Tuple2Map"),
|
||||
("read_only_space", 0x059c9): (114, "Tuple3Map"),
|
||||
("read_only_space", 0x05a19): (116, "WasmCapiFunctionDataMap"),
|
||||
("read_only_space", 0x05a69): (117, "WasmDebugInfoMap"),
|
||||
("read_only_space", 0x05ab9): (118, "WasmExceptionTagMap"),
|
||||
("read_only_space", 0x05b09): (119, "WasmExportedFunctionDataMap"),
|
||||
("read_only_space", 0x05b59): (120, "CallableTaskMap"),
|
||||
("read_only_space", 0x05ba9): (121, "CallbackTaskMap"),
|
||||
("read_only_space", 0x05bf9): (122, "PromiseFulfillReactionJobTaskMap"),
|
||||
("read_only_space", 0x05c49): (123, "PromiseRejectReactionJobTaskMap"),
|
||||
("read_only_space", 0x05c99): (124, "PromiseResolveThenableJobTaskMap"),
|
||||
("read_only_space", 0x05ce9): (125, "FinalizationGroupCleanupJobTaskMap"),
|
||||
("read_only_space", 0x05d39): (126, "AllocationSiteWithWeakNextMap"),
|
||||
("read_only_space", 0x05d89): (126, "AllocationSiteWithoutWeakNextMap"),
|
||||
("read_only_space", 0x05dd9): (161, "LoadHandler1Map"),
|
||||
("read_only_space", 0x05e29): (161, "LoadHandler2Map"),
|
||||
("read_only_space", 0x05e79): (161, "LoadHandler3Map"),
|
||||
("read_only_space", 0x05ec9): (169, "StoreHandler0Map"),
|
||||
("read_only_space", 0x05f19): (169, "StoreHandler1Map"),
|
||||
("read_only_space", 0x05f69): (169, "StoreHandler2Map"),
|
||||
("read_only_space", 0x05fb9): (169, "StoreHandler3Map"),
|
||||
("map_space", 0x00141): (1057, "ExternalMap"),
|
||||
("map_space", 0x00191): (1073, "JSMessageObjectMap"),
|
||||
}
|
||||
@ -404,7 +404,9 @@ KNOWN_OBJECTS = {
|
||||
("read_only_space", 0x02b61): "MinusInfinityValue",
|
||||
("read_only_space", 0x02b71): "SelfReferenceMarker",
|
||||
("read_only_space", 0x02bc9): "OffHeapTrampolineRelocationInfo",
|
||||
("read_only_space", 0x02be1): "HashSeed",
|
||||
("read_only_space", 0x02be1): "TrampolineTrivialCodeDataContainer",
|
||||
("read_only_space", 0x02bf9): "TrampolinePromiseRejectionCodeDataContainer",
|
||||
("read_only_space", 0x02c11): "HashSeed",
|
||||
("old_space", 0x00141): "ArgumentsIteratorAccessor",
|
||||
("old_space", 0x001b1): "ArrayLengthAccessor",
|
||||
("old_space", 0x00221): "BoundFunctionLengthAccessor",
|
||||
|
Loading…
Reference in New Issue
Block a user