Commit 365e2417 authored by Creddy's avatar Creddy Committed by Commit Bot

[interpreter][runtime] Avoid AllocationSites for Array literals in oneshot code

No need to create allocation site for array literals in oneshot code since
they are executed only once. The interpreter emits a runtime call to
CreateArrayLiteralWithoutAllocationSite for creating literals in
oneshot code instead.

Change-Id: I285879c84759ff9e2ce281e9548112f52ce5e7d1
Reviewed-on: https://chromium-review.googlesource.com/1167843Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Commit-Queue: Chandan Reddy <chandanreddy@google.com>
Cr-Commit-Position: refs/heads/master@{#55349}
parent 3a80af30
......@@ -276,6 +276,7 @@ Type::bitset BitsetType::Lub(HeapObjectType const& type) {
case BYTE_ARRAY_TYPE:
case BYTECODE_ARRAY_TYPE:
case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
case ARRAY_BOILERPLATE_DESCRIPTION_TYPE:
case DESCRIPTOR_ARRAY_TYPE:
case TRANSITION_ARRAY_TYPE:
case FEEDBACK_CELL_TYPE:
......@@ -330,7 +331,6 @@ Type::bitset BitsetType::Lub(HeapObjectType const& type) {
case INTERPRETER_DATA_TYPE:
case TUPLE2_TYPE:
case TUPLE3_TYPE:
case ARRAY_BOILERPLATE_DESCRIPTION_TYPE:
case WASM_DEBUG_INFO_TYPE:
case WASM_EXPORTED_FUNCTION_DATA_TYPE:
case LOAD_HANDLER_TYPE:
......
......@@ -309,6 +309,7 @@ bool IntrinsicHasNoSideEffect(Runtime::FunctionId id) {
V(BigIntToNumber) \
/* Literals */ \
V(CreateArrayLiteral) \
V(CreateArrayLiteralWithoutAllocationSite) \
V(CreateObjectLiteral) \
V(CreateObjectLiteralWithoutAllocationSite) \
V(CreateRegExpLiteral) \
......
......@@ -21,6 +21,7 @@
#include "src/objects/debug-objects.h"
#include "src/objects/descriptor-array.h"
#include "src/objects/dictionary.h"
#include "src/objects/literal-objects-inl.h"
#include "src/objects/map.h"
#include "src/objects/microtask.h"
#include "src/objects/module.h"
......@@ -522,6 +523,20 @@ bool Heap::CreateInitialMaps() {
set_empty_object_boilerplate_description(
ObjectBoilerplateDescription::cast(obj));
{
// Empty array boilerplate description
AllocationResult alloc =
Allocate(roots.array_boilerplate_description_map(), RO_SPACE);
if (!alloc.To(&obj)) return false;
ArrayBoilerplateDescription::cast(obj)->set_constant_elements(
roots.empty_fixed_array());
ArrayBoilerplateDescription::cast(obj)->set_elements_kind(
ElementsKind::PACKED_ELEMENTS);
}
set_empty_array_boilerplate_description(
ArrayBoilerplateDescription::cast(obj));
{
AllocationResult allocation = Allocate(roots.boolean_map(), RO_SPACE);
if (!allocation.To(&obj)) return false;
......
......@@ -2432,22 +2432,41 @@ void BytecodeGenerator::BuildArrayLiteralElementsInsertion(
void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
expr->InitDepthAndFlags();
uint8_t flags = CreateArrayLiteralFlags::Encode(
expr->IsFastCloningSupported(), expr->ComputeFlags());
// Deep-copy the literal boilerplate.
int literal_index = feedback_index(feedback_spec()->AddLiteralSlot());
if (expr->is_empty()) {
bool is_empty = expr->is_empty();
bool optimize_as_one_shot = ShouldOptimizeAsOneShot();
size_t entry;
if (is_empty && optimize_as_one_shot) {
entry = builder()->EmptyArrayBoilerplateDescriptionConstantPoolEntry();
} else if (!is_empty) {
entry = builder()->AllocateDeferredConstantPoolEntry();
array_literals_.push_back(std::make_pair(expr, entry));
}
if (optimize_as_one_shot) {
// Create array literal without any allocation sites
RegisterAllocationScope register_scope(this);
RegisterList args = register_allocator()->NewRegisterList(2);
builder()
->LoadConstantPoolEntry(entry)
.StoreAccumulatorInRegister(args[0])
.LoadLiteral(Smi::FromInt(flags))
.StoreAccumulatorInRegister(args[1])
.CallRuntime(Runtime::kCreateArrayLiteralWithoutAllocationSite, args);
} else if (is_empty) {
// Empty array literal fast-path.
int literal_index = feedback_index(feedback_spec()->AddLiteralSlot());
DCHECK(expr->IsFastCloningSupported());
builder()->CreateEmptyArrayLiteral(literal_index);
return;
} else {
// Deep-copy the literal boilerplate
int literal_index = feedback_index(feedback_spec()->AddLiteralSlot());
builder()->CreateArrayLiteral(entry, literal_index, flags);
}
uint8_t flags = CreateArrayLiteralFlags::Encode(
expr->IsFastCloningSupported(), expr->ComputeFlags());
size_t entry = builder()->AllocateDeferredConstantPoolEntry();
builder()->CreateArrayLiteral(entry, literal_index, flags);
array_literals_.push_back(std::make_pair(expr, entry));
Register literal = register_allocator()->NewRegister();
builder()->StoreAccumulatorInRegister(literal);
// Insert all elements except the constant ones, since they are already there.
......
......@@ -25,6 +25,7 @@ namespace interpreter {
V(AsyncIteratorSymbol, async_iterator_symbol) \
V(ClassFieldsSymbol, class_fields_symbol) \
V(EmptyObjectBoilerplateDescription, empty_object_boilerplate_description) \
V(EmptyArrayBoilerplateDescription, empty_array_boilerplate_description) \
V(EmptyFixedArray, empty_fixed_array) \
V(HomeObjectSymbol, home_object_symbol) \
V(IteratorSymbol, iterator_symbol) \
......
......@@ -166,6 +166,8 @@ namespace internal {
V(ByteArray, empty_byte_array, EmptyByteArray) \
V(ObjectBoilerplateDescription, empty_object_boilerplate_description, \
EmptyObjectBoilerplateDescription) \
V(ArrayBoilerplateDescription, empty_array_boilerplate_description, \
EmptyArrayBoilerplateDescription) \
V(FixedTypedArrayBase, empty_fixed_uint8_array, EmptyFixedUint8Array) \
V(FixedTypedArrayBase, empty_fixed_int8_array, EmptyFixedInt8Array) \
V(FixedTypedArrayBase, empty_fixed_uint16_array, EmptyFixedUint16Array) \
......
......@@ -564,6 +564,16 @@ RUNTIME_FUNCTION(Runtime_CreateObjectLiteralWithoutAllocationSite) {
isolate, description, flags));
}
RUNTIME_FUNCTION(Runtime_CreateArrayLiteralWithoutAllocationSite) {
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
CONVERT_ARG_HANDLE_CHECKED(ArrayBoilerplateDescription, description, 0);
CONVERT_SMI_ARG_CHECKED(flags, 1);
RETURN_RESULT_OR_FAILURE(
isolate, CreateLiteralWithoutAllocationSite<ArrayLiteralHelper>(
isolate, description, flags));
}
RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) {
HandleScope scope(isolate);
DCHECK_EQ(4, args.length());
......
......@@ -284,6 +284,7 @@ namespace internal {
#define FOR_EACH_INTRINSIC_LITERALS(F) \
F(CreateArrayLiteral, 4, 1) \
F(CreateArrayLiteralWithoutAllocationSite, 2, 1) \
F(CreateObjectLiteral, 4, 1) \
F(CreateObjectLiteralWithoutAllocationSite, 2, 1) \
F(CreateRegExpLiteral, 4, 1)
......
......@@ -3682,18 +3682,48 @@ TEST(AllocationSiteCreation) {
i::FLAG_enable_one_shot_optimization = true;
// Array literals.
CheckNumberOfAllocations(heap, "(function f1() { return []; })()", 1, 0);
CheckNumberOfAllocations(heap, "(function f2() { return [1, 2]; })()", 1, 0);
CheckNumberOfAllocations(heap, "(function f3() { return [[1], [2]]; })()", 1,
2);
CheckNumberOfAllocations(heap, "function f1() { return []; }; f1()", 1, 0);
CheckNumberOfAllocations(heap, "function f2() { return [1, 2]; }; f2()", 1,
0);
CheckNumberOfAllocations(heap, "function f3() { return [[1], [2]]; }; f3()",
1, 2);
CheckNumberOfAllocations(heap,
"(function f4() { "
"function f4() { "
"return [0, [1, 1.1, 1.2, "
"], 1.5, [2.1, 2.2], 3];"
"})()",
"}; f4();",
1, 2);
// No allocation sites within IIFE/top-level
CheckNumberOfAllocations(heap,
R"(
(function f4() {
return [ 0, [ 1, 1.1, 1.2,], 1.5, [2.1, 2.2], 3 ];
})();
)",
0, 0);
CheckNumberOfAllocations(heap,
R"(
l = [ 1, 2, 3, 4];
)",
0, 0);
CheckNumberOfAllocations(heap,
R"(
a = [];
)",
0, 0);
CheckNumberOfAllocations(heap,
R"(
(function f4() {
return [];
})();
)",
0, 0);
// Object literals have lazy AllocationSites
CheckNumberOfAllocations(heap, "function f5() { return {}; }; f5(); ", 0, 0);
......
......@@ -334,3 +334,75 @@ constant pool: [
handlers: [
]
---
snippet: "
(function() {
a = [0, [1, 1,2,], 3];
return arguments.callee;
})();
"
frame size: 4
parameter count: 1
bytecode array length: 32
bytecodes: [
B(CreateMappedArguments),
B(Star), R(0),
/* 16 E> */ B(StackCheck),
/* 29 S> */ B(LdaConstant), U8(0),
B(Star), R(1),
B(LdaSmi), I8(4),
B(Star), R(2),
B(CallRuntime), U16(Runtime::kCreateArrayLiteralWithoutAllocationSite), R(1), U8(2),
/* 31 E> */ B(StaGlobal), U8(1), U8(0),
/* 60 S> */ B(LdaConstant), U8(2),
B(Star), R(3),
B(Mov), R(0), R(2),
/* 77 E> */ B(InvokeIntrinsic), U8(Runtime::k_GetProperty), R(2), U8(2),
/* 84 S> */ B(Return),
]
constant pool: [
ARRAY_BOILERPLATE_DESCRIPTION_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["a"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["callee"],
]
handlers: [
]
---
snippet: "
(function() {
a = [];
return arguments.callee;
})();
"
frame size: 4
parameter count: 1
bytecode array length: 32
bytecodes: [
B(CreateMappedArguments),
B(Star), R(0),
/* 16 E> */ B(StackCheck),
/* 29 S> */ B(LdaConstant), U8(0),
B(Star), R(1),
B(LdaSmi), I8(37),
B(Star), R(2),
B(CallRuntime), U16(Runtime::kCreateArrayLiteralWithoutAllocationSite), R(1), U8(2),
/* 31 E> */ B(StaGlobal), U8(1), U8(0),
/* 45 S> */ B(LdaConstant), U8(2),
B(Star), R(3),
B(Mov), R(0), R(2),
/* 62 E> */ B(InvokeIntrinsic), U8(Runtime::k_GetProperty), R(2), U8(2),
/* 69 S> */ B(Return),
]
constant pool: [
ARRAY_BOILERPLATE_DESCRIPTION_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["a"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["callee"],
]
handlers: [
]
......@@ -367,3 +367,57 @@ constant pool: [
handlers: [
]
---
snippet: "
a = [1.1, [2.2, 4.5]];
"
frame size: 3
parameter count: 1
bytecode array length: 20
bytecodes: [
/* 0 E> */ B(StackCheck),
/* 7 S> */ B(LdaConstant), U8(0),
B(Star), R(1),
B(LdaSmi), I8(4),
B(Star), R(2),
B(CallRuntime), U16(Runtime::kCreateArrayLiteralWithoutAllocationSite), R(1), U8(2),
/* 9 E> */ B(StaGlobal), U8(1), U8(0),
B(Star), R(0),
/* 36 S> */ B(Return),
]
constant pool: [
ARRAY_BOILERPLATE_DESCRIPTION_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["a"],
]
handlers: [
]
---
snippet: "
b = [];
"
frame size: 3
parameter count: 1
bytecode array length: 20
bytecodes: [
/* 0 E> */ B(StackCheck),
/* 7 S> */ B(LdaConstant), U8(0),
B(Star), R(1),
B(LdaSmi), I8(37),
B(Star), R(2),
B(CallRuntime), U16(Runtime::kCreateArrayLiteralWithoutAllocationSite), R(1), U8(2),
/* 9 E> */ B(StaGlobal), U8(1), U8(0),
B(Star), R(0),
/* 21 S> */ B(Return),
]
constant pool: [
ARRAY_BOILERPLATE_DESCRIPTION_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["b"],
]
handlers: [
]
......@@ -495,6 +495,14 @@ TEST(PropertyLoadStoreOneShot) {
l['d'] = 3;
}
)",
R"(
a = [1.1, [2.2, 4.5]];
)",
R"(
b = [];
)",
};
CHECK(CompareTexts(BuildActual(printer, snippets),
LoadGolden("PropertyLoadStoreOneShot.golden")));
......@@ -605,6 +613,20 @@ TEST(IIFEWithOneshotOpt) {
return arguments.callee;
})();
)",
R"(
(function() {
a = [0, [1, 1,2,], 3];
return arguments.callee;
})();
)",
R"(
(function() {
a = [];
return arguments.callee;
})();
)",
};
CHECK(CompareTexts(BuildActual(printer, snippets),
LoadGolden("IIFEWithOneshotOpt.golden")));
......
......@@ -3517,12 +3517,18 @@ TEST(SamplingHeapProfilerRateAgnosticEstimates) {
// what we expect in this test.
v8::internal::FLAG_always_opt = false;
// Disable compilation cache to force compilation in both cases
v8::internal::FLAG_compilation_cache = false;
// Suppress randomness to avoid flakiness in tests.
v8::internal::FLAG_sampling_heap_profiler_suppress_randomness = true;
// stress_incremental_marking adds randomness to the test.
v8::internal::FLAG_stress_incremental_marking = false;
// warmup compilation
CompileRun(simple_sampling_heap_profiler_script);
int count_1024 = 0;
{
heap_profiler->StartSamplingHeapProfiler(1024);
......
......@@ -281,35 +281,35 @@ KNOWN_MAPS = {
("RO_SPACE", 0x046b9): (148, "FixedBigInt64ArrayMap"),
("RO_SPACE", 0x04709): (131, "SelfReferenceMarkerMap"),
("RO_SPACE", 0x04771): (171, "Tuple2Map"),
("RO_SPACE", 0x04a99): (161, "InterceptorInfoMap"),
("RO_SPACE", 0x04b91): (169, "ScriptMap"),
("RO_SPACE", 0x09a39): (154, "AccessorInfoMap"),
("RO_SPACE", 0x09a89): (153, "AccessCheckInfoMap"),
("RO_SPACE", 0x09ad9): (155, "AccessorPairMap"),
("RO_SPACE", 0x09b29): (156, "AliasedArgumentsEntryMap"),
("RO_SPACE", 0x09b79): (157, "AllocationMementoMap"),
("RO_SPACE", 0x09bc9): (158, "AsyncGeneratorRequestMap"),
("RO_SPACE", 0x09c19): (159, "DebugInfoMap"),
("RO_SPACE", 0x09c69): (160, "FunctionTemplateInfoMap"),
("RO_SPACE", 0x09cb9): (162, "InterpreterDataMap"),
("RO_SPACE", 0x09d09): (163, "ModuleInfoEntryMap"),
("RO_SPACE", 0x09d59): (164, "ModuleMap"),
("RO_SPACE", 0x09da9): (165, "ObjectTemplateInfoMap"),
("RO_SPACE", 0x09df9): (166, "PromiseCapabilityMap"),
("RO_SPACE", 0x09e49): (167, "PromiseReactionMap"),
("RO_SPACE", 0x09e99): (168, "PrototypeInfoMap"),
("RO_SPACE", 0x09ee9): (170, "StackFrameInfoMap"),
("RO_SPACE", 0x09f39): (172, "Tuple3Map"),
("RO_SPACE", 0x09f89): (173, "ArrayBoilerplateDescriptionMap"),
("RO_SPACE", 0x09fd9): (174, "WasmDebugInfoMap"),
("RO_SPACE", 0x0a029): (175, "WasmExportedFunctionDataMap"),
("RO_SPACE", 0x0a079): (176, "CallableTaskMap"),
("RO_SPACE", 0x0a0c9): (177, "CallbackTaskMap"),
("RO_SPACE", 0x0a119): (178, "PromiseFulfillReactionJobTaskMap"),
("RO_SPACE", 0x0a169): (179, "PromiseRejectReactionJobTaskMap"),
("RO_SPACE", 0x0a1b9): (180, "PromiseResolveThenableJobTaskMap"),
("RO_SPACE", 0x0a209): (181, "AllocationSiteMap"),
("RO_SPACE", 0x0a259): (181, "AllocationSiteMap"),
("RO_SPACE", 0x04811): (173, "ArrayBoilerplateDescriptionMap"),
("RO_SPACE", 0x04b01): (161, "InterceptorInfoMap"),
("RO_SPACE", 0x04bf9): (169, "ScriptMap"),
("RO_SPACE", 0x09aa1): (154, "AccessorInfoMap"),
("RO_SPACE", 0x09af1): (153, "AccessCheckInfoMap"),
("RO_SPACE", 0x09b41): (155, "AccessorPairMap"),
("RO_SPACE", 0x09b91): (156, "AliasedArgumentsEntryMap"),
("RO_SPACE", 0x09be1): (157, "AllocationMementoMap"),
("RO_SPACE", 0x09c31): (158, "AsyncGeneratorRequestMap"),
("RO_SPACE", 0x09c81): (159, "DebugInfoMap"),
("RO_SPACE", 0x09cd1): (160, "FunctionTemplateInfoMap"),
("RO_SPACE", 0x09d21): (162, "InterpreterDataMap"),
("RO_SPACE", 0x09d71): (163, "ModuleInfoEntryMap"),
("RO_SPACE", 0x09dc1): (164, "ModuleMap"),
("RO_SPACE", 0x09e11): (165, "ObjectTemplateInfoMap"),
("RO_SPACE", 0x09e61): (166, "PromiseCapabilityMap"),
("RO_SPACE", 0x09eb1): (167, "PromiseReactionMap"),
("RO_SPACE", 0x09f01): (168, "PrototypeInfoMap"),
("RO_SPACE", 0x09f51): (170, "StackFrameInfoMap"),
("RO_SPACE", 0x09fa1): (172, "Tuple3Map"),
("RO_SPACE", 0x09ff1): (174, "WasmDebugInfoMap"),
("RO_SPACE", 0x0a041): (175, "WasmExportedFunctionDataMap"),
("RO_SPACE", 0x0a091): (176, "CallableTaskMap"),
("RO_SPACE", 0x0a0e1): (177, "CallbackTaskMap"),
("RO_SPACE", 0x0a131): (178, "PromiseFulfillReactionJobTaskMap"),
("RO_SPACE", 0x0a181): (179, "PromiseRejectReactionJobTaskMap"),
("RO_SPACE", 0x0a1d1): (180, "PromiseResolveThenableJobTaskMap"),
("RO_SPACE", 0x0a221): (181, "AllocationSiteMap"),
("RO_SPACE", 0x0a271): (181, "AllocationSiteMap"),
("MAP_SPACE", 0x02201): (1057, "ExternalMap"),
("MAP_SPACE", 0x02251): (1072, "JSMessageObjectMap"),
}
......@@ -334,24 +334,24 @@ KNOWN_OBJECTS = {
("RO_SPACE", 0x02f39): "OptimizedOut",
("RO_SPACE", 0x02fe1): "StaleRegister",
("RO_SPACE", 0x047d1): "EmptyByteArray",
("RO_SPACE", 0x047f9): "EmptyFixedUint8Array",
("RO_SPACE", 0x04819): "EmptyFixedInt8Array",
("RO_SPACE", 0x04839): "EmptyFixedUint16Array",
("RO_SPACE", 0x04859): "EmptyFixedInt16Array",
("RO_SPACE", 0x04879): "EmptyFixedUint32Array",
("RO_SPACE", 0x04899): "EmptyFixedInt32Array",
("RO_SPACE", 0x048b9): "EmptyFixedFloat32Array",
("RO_SPACE", 0x048d9): "EmptyFixedFloat64Array",
("RO_SPACE", 0x048f9): "EmptyFixedUint8ClampedArray",
("RO_SPACE", 0x04959): "EmptySloppyArgumentsElements",
("RO_SPACE", 0x04979): "EmptySlowElementDictionary",
("RO_SPACE", 0x049c1): "EmptyOrderedHashMap",
("RO_SPACE", 0x049e9): "EmptyOrderedHashSet",
("RO_SPACE", 0x04a21): "EmptyPropertyCell",
("RO_SPACE", 0x04b01): "InfinityValue",
("RO_SPACE", 0x04b11): "MinusZeroValue",
("RO_SPACE", 0x04b21): "MinusInfinityValue",
("RO_SPACE", 0x04b31): "SelfReferenceMarker",
("RO_SPACE", 0x04861): "EmptyFixedUint8Array",
("RO_SPACE", 0x04881): "EmptyFixedInt8Array",
("RO_SPACE", 0x048a1): "EmptyFixedUint16Array",
("RO_SPACE", 0x048c1): "EmptyFixedInt16Array",
("RO_SPACE", 0x048e1): "EmptyFixedUint32Array",
("RO_SPACE", 0x04901): "EmptyFixedInt32Array",
("RO_SPACE", 0x04921): "EmptyFixedFloat32Array",
("RO_SPACE", 0x04941): "EmptyFixedFloat64Array",
("RO_SPACE", 0x04961): "EmptyFixedUint8ClampedArray",
("RO_SPACE", 0x049c1): "EmptySloppyArgumentsElements",
("RO_SPACE", 0x049e1): "EmptySlowElementDictionary",
("RO_SPACE", 0x04a29): "EmptyOrderedHashMap",
("RO_SPACE", 0x04a51): "EmptyOrderedHashSet",
("RO_SPACE", 0x04a89): "EmptyPropertyCell",
("RO_SPACE", 0x04b69): "InfinityValue",
("RO_SPACE", 0x04b79): "MinusZeroValue",
("RO_SPACE", 0x04b89): "MinusInfinityValue",
("RO_SPACE", 0x04b99): "SelfReferenceMarker",
("OLD_SPACE", 0x02211): "EmptyScript",
("OLD_SPACE", 0x02291): "ManyClosuresCell",
("OLD_SPACE", 0x022b1): "NoElementsProtector",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment