Commit 3e572613 authored by jgruber's avatar jgruber Committed by Commit Bot

[builtins] Move remaining Array constructor stubs to builtins

Calls from embedded builtins to stubs are expensive due to the
indirection through the builtins constants table. This moves
all remaining Array constructor stubs to builtins.

Bug: v8:6666
Change-Id: I5989a7480697a506a1bae1929ddd2e3f1d655048
Reviewed-on: https://chromium-review.googlesource.com/1074759
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53399}
parent 54f77c42
......@@ -4011,5 +4011,173 @@ TF_BUILTIN(ArrayPrototypeFlatMap, CodeStubAssembler) {
{ ThrowTypeError(context, MessageTemplate::kMapperFunctionNonCallable); }
}
void ArrayBuiltinsAssembler::GenerateConstructor(
Node* context, Node* array_function, Node* array_map, Node* array_size,
Node* allocation_site, ElementsKind elements_kind,
AllocationSiteMode mode) {
Label ok(this);
Label smi_size(this);
Label small_smi_size(this);
Label call_runtime(this, Label::kDeferred);
Branch(TaggedIsSmi(array_size), &smi_size, &call_runtime);
BIND(&smi_size);
if (IsFastPackedElementsKind(elements_kind)) {
Label abort(this, Label::kDeferred);
Branch(SmiEqual(CAST(array_size), SmiConstant(0)), &small_smi_size, &abort);
BIND(&abort);
Node* reason = SmiConstant(AbortReason::kAllocatingNonEmptyPackedArray);
TailCallRuntime(Runtime::kAbort, context, reason);
} else {
int element_size =
IsDoubleElementsKind(elements_kind) ? kDoubleSize : kPointerSize;
int max_fast_elements =
(kMaxRegularHeapObjectSize - FixedArray::kHeaderSize - JSArray::kSize -
AllocationMemento::kSize) /
element_size;
Branch(SmiAboveOrEqual(CAST(array_size), SmiConstant(max_fast_elements)),
&call_runtime, &small_smi_size);
}
BIND(&small_smi_size);
{
Node* array = AllocateJSArray(
elements_kind, array_map, array_size, array_size,
mode == DONT_TRACK_ALLOCATION_SITE ? nullptr : allocation_site,
CodeStubAssembler::SMI_PARAMETERS);
Return(array);
}
BIND(&call_runtime);
{
TailCallRuntime(Runtime::kNewArray, context, array_function, array_size,
array_function, allocation_site);
}
}
void ArrayBuiltinsAssembler::GenerateArrayNoArgumentConstructor(
ElementsKind kind, AllocationSiteOverrideMode mode) {
typedef ArrayNoArgumentConstructorDescriptor Descriptor;
Node* native_context = LoadObjectField(Parameter(Descriptor::kFunction),
JSFunction::kContextOffset);
bool track_allocation_site =
AllocationSite::ShouldTrack(kind) && mode != DISABLE_ALLOCATION_SITES;
Node* allocation_site =
track_allocation_site ? Parameter(Descriptor::kAllocationSite) : nullptr;
Node* array_map = LoadJSArrayElementsMap(kind, native_context);
Node* array = AllocateJSArray(
kind, array_map, IntPtrConstant(JSArray::kPreallocatedArrayElements),
SmiConstant(0), allocation_site);
Return(array);
}
void ArrayBuiltinsAssembler::GenerateArraySingleArgumentConstructor(
ElementsKind kind, AllocationSiteOverrideMode mode) {
typedef ArraySingleArgumentConstructorDescriptor Descriptor;
Node* context = Parameter(Descriptor::kContext);
Node* function = Parameter(Descriptor::kFunction);
Node* native_context = LoadObjectField(function, JSFunction::kContextOffset);
Node* array_map = LoadJSArrayElementsMap(kind, native_context);
AllocationSiteMode allocation_site_mode = DONT_TRACK_ALLOCATION_SITE;
if (mode == DONT_OVERRIDE) {
allocation_site_mode = AllocationSite::ShouldTrack(kind)
? TRACK_ALLOCATION_SITE
: DONT_TRACK_ALLOCATION_SITE;
}
Node* array_size = Parameter(Descriptor::kArraySizeSmiParameter);
Node* allocation_site = Parameter(Descriptor::kAllocationSite);
GenerateConstructor(context, function, array_map, array_size, allocation_site,
kind, allocation_site_mode);
}
void ArrayBuiltinsAssembler::GenerateInternalArrayNoArgumentConstructor(
ElementsKind kind) {
typedef ArrayNoArgumentConstructorDescriptor Descriptor;
Node* array_map = LoadObjectField(Parameter(Descriptor::kFunction),
JSFunction::kPrototypeOrInitialMapOffset);
Node* array = AllocateJSArray(
kind, array_map, IntPtrConstant(JSArray::kPreallocatedArrayElements),
SmiConstant(0));
Return(array);
}
void ArrayBuiltinsAssembler::GenerateInternalArraySingleArgumentConstructor(
ElementsKind kind) {
typedef ArraySingleArgumentConstructorDescriptor Descriptor;
Node* context = Parameter(Descriptor::kContext);
Node* function = Parameter(Descriptor::kFunction);
Node* array_map =
LoadObjectField(function, JSFunction::kPrototypeOrInitialMapOffset);
Node* array_size = Parameter(Descriptor::kArraySizeSmiParameter);
Node* allocation_site = UndefinedConstant();
GenerateConstructor(context, function, array_map, array_size, allocation_site,
kind, DONT_TRACK_ALLOCATION_SITE);
}
#define GENERATE_ARRAY_CTOR(name, kind_camel, kind_caps, mode_camel, \
mode_caps) \
TF_BUILTIN(Array##name##Constructor_##kind_camel##_##mode_camel, \
ArrayBuiltinsAssembler) { \
GenerateArray##name##Constructor(kind_caps, mode_caps); \
}
// The ArrayNoArgumentConstructor builtin family.
GENERATE_ARRAY_CTOR(NoArgument, PackedSmi, PACKED_SMI_ELEMENTS, DontOverride,
DONT_OVERRIDE);
GENERATE_ARRAY_CTOR(NoArgument, HoleySmi, HOLEY_SMI_ELEMENTS, DontOverride,
DONT_OVERRIDE);
GENERATE_ARRAY_CTOR(NoArgument, PackedSmi, PACKED_SMI_ELEMENTS,
DisableAllocationSites, DISABLE_ALLOCATION_SITES);
GENERATE_ARRAY_CTOR(NoArgument, HoleySmi, HOLEY_SMI_ELEMENTS,
DisableAllocationSites, DISABLE_ALLOCATION_SITES);
GENERATE_ARRAY_CTOR(NoArgument, Packed, PACKED_ELEMENTS, DisableAllocationSites,
DISABLE_ALLOCATION_SITES);
GENERATE_ARRAY_CTOR(NoArgument, Holey, HOLEY_ELEMENTS, DisableAllocationSites,
DISABLE_ALLOCATION_SITES);
GENERATE_ARRAY_CTOR(NoArgument, PackedDouble, PACKED_DOUBLE_ELEMENTS,
DisableAllocationSites, DISABLE_ALLOCATION_SITES);
GENERATE_ARRAY_CTOR(NoArgument, HoleyDouble, HOLEY_DOUBLE_ELEMENTS,
DisableAllocationSites, DISABLE_ALLOCATION_SITES);
// The ArraySingleArgumentConstructor builtin family.
GENERATE_ARRAY_CTOR(SingleArgument, PackedSmi, PACKED_SMI_ELEMENTS,
DontOverride, DONT_OVERRIDE);
GENERATE_ARRAY_CTOR(SingleArgument, HoleySmi, HOLEY_SMI_ELEMENTS, DontOverride,
DONT_OVERRIDE);
GENERATE_ARRAY_CTOR(SingleArgument, PackedSmi, PACKED_SMI_ELEMENTS,
DisableAllocationSites, DISABLE_ALLOCATION_SITES);
GENERATE_ARRAY_CTOR(SingleArgument, HoleySmi, HOLEY_SMI_ELEMENTS,
DisableAllocationSites, DISABLE_ALLOCATION_SITES);
GENERATE_ARRAY_CTOR(SingleArgument, Packed, PACKED_ELEMENTS,
DisableAllocationSites, DISABLE_ALLOCATION_SITES);
GENERATE_ARRAY_CTOR(SingleArgument, Holey, HOLEY_ELEMENTS,
DisableAllocationSites, DISABLE_ALLOCATION_SITES);
GENERATE_ARRAY_CTOR(SingleArgument, PackedDouble, PACKED_DOUBLE_ELEMENTS,
DisableAllocationSites, DISABLE_ALLOCATION_SITES);
GENERATE_ARRAY_CTOR(SingleArgument, HoleyDouble, HOLEY_DOUBLE_ELEMENTS,
DisableAllocationSites, DISABLE_ALLOCATION_SITES);
#undef GENERATE_ARRAY_CTOR
#define GENERATE_INTERNAL_ARRAY_CTOR(name, kind_camel, kind_caps) \
TF_BUILTIN(InternalArray##name##Constructor_##kind_camel, \
ArrayBuiltinsAssembler) { \
GenerateInternalArray##name##Constructor(kind_caps); \
}
GENERATE_INTERNAL_ARRAY_CTOR(NoArgument, Packed, PACKED_ELEMENTS);
GENERATE_INTERNAL_ARRAY_CTOR(NoArgument, Holey, HOLEY_ELEMENTS);
GENERATE_INTERNAL_ARRAY_CTOR(SingleArgument, Packed, PACKED_ELEMENTS);
GENERATE_INTERNAL_ARRAY_CTOR(SingleArgument, Holey, HOLEY_ELEMENTS);
#undef GENERATE_INTERNAL_ARRAY_CTOR
} // namespace internal
} // namespace v8
......@@ -106,6 +106,16 @@ class ArrayBuiltinsAssembler : public BaseBuiltinsFromDSLAssembler {
MissingPropertyMode missing_property_mode,
ForEachDirection direction = ForEachDirection::kForward);
void GenerateConstructor(Node* context, Node* array_function, Node* array_map,
Node* array_size, Node* allocation_site,
ElementsKind elements_kind, AllocationSiteMode mode);
void GenerateArrayNoArgumentConstructor(ElementsKind kind,
AllocationSiteOverrideMode mode);
void GenerateArraySingleArgumentConstructor(ElementsKind kind,
AllocationSiteOverrideMode mode);
void GenerateInternalArrayNoArgumentConstructor(ElementsKind kind);
void GenerateInternalArraySingleArgumentConstructor(ElementsKind kind);
private:
static ElementsKind ElementsKindForInstanceType(InstanceType type);
......
......@@ -237,9 +237,48 @@ namespace internal {
/* Array */ \
ASM(ArrayConstructor) \
ASM(ArrayConstructorImpl) \
TFC(ArrayNoArgumentConstructor_PackedSmi_DontOverride, \
ArrayNoArgumentConstructor, 1) \
TFC(ArrayNoArgumentConstructor_HoleySmi_DontOverride, \
ArrayNoArgumentConstructor, 1) \
TFC(ArrayNoArgumentConstructor_PackedSmi_DisableAllocationSites, \
ArrayNoArgumentConstructor, 1) \
TFC(ArrayNoArgumentConstructor_HoleySmi_DisableAllocationSites, \
ArrayNoArgumentConstructor, 1) \
TFC(ArrayNoArgumentConstructor_Packed_DisableAllocationSites, \
ArrayNoArgumentConstructor, 1) \
TFC(ArrayNoArgumentConstructor_Holey_DisableAllocationSites, \
ArrayNoArgumentConstructor, 1) \
TFC(ArrayNoArgumentConstructor_PackedDouble_DisableAllocationSites, \
ArrayNoArgumentConstructor, 1) \
TFC(ArrayNoArgumentConstructor_HoleyDouble_DisableAllocationSites, \
ArrayNoArgumentConstructor, 1) \
TFC(ArraySingleArgumentConstructor_PackedSmi_DontOverride, \
ArraySingleArgumentConstructor, 1) \
TFC(ArraySingleArgumentConstructor_HoleySmi_DontOverride, \
ArraySingleArgumentConstructor, 1) \
TFC(ArraySingleArgumentConstructor_PackedSmi_DisableAllocationSites, \
ArraySingleArgumentConstructor, 1) \
TFC(ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites, \
ArraySingleArgumentConstructor, 1) \
TFC(ArraySingleArgumentConstructor_Packed_DisableAllocationSites, \
ArraySingleArgumentConstructor, 1) \
TFC(ArraySingleArgumentConstructor_Holey_DisableAllocationSites, \
ArraySingleArgumentConstructor, 1) \
TFC(ArraySingleArgumentConstructor_PackedDouble_DisableAllocationSites, \
ArraySingleArgumentConstructor, 1) \
TFC(ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites, \
ArraySingleArgumentConstructor, 1) \
ASM(ArrayNArgumentsConstructor) \
ASM(InternalArrayConstructor) \
ASM(InternalArrayConstructorImpl) \
TFC(InternalArrayNoArgumentConstructor_Packed, ArrayNoArgumentConstructor, \
1) \
TFC(InternalArrayNoArgumentConstructor_Holey, ArrayNoArgumentConstructor, 1) \
TFC(InternalArraySingleArgumentConstructor_Packed, \
ArraySingleArgumentConstructor, 1) \
TFC(InternalArraySingleArgumentConstructor_Holey, \
ArraySingleArgumentConstructor, 1) \
CPP(ArrayConcat) \
/* ES6 #sec-array.isarray */ \
TFJ(ArrayIsArray, 1, kArg) \
......
......@@ -337,30 +337,105 @@ Callable CodeFactory::InterpreterOnStackReplacement(Isolate* isolate) {
Callable CodeFactory::ArrayNoArgumentConstructor(
Isolate* isolate, ElementsKind kind,
AllocationSiteOverrideMode override_mode) {
ArrayNoArgumentConstructorStub stub(isolate, kind, override_mode);
return make_callable(stub);
#define CASE(kind_caps, kind_camel, mode_camel) \
case kind_caps: \
return Callable( \
BUILTIN_CODE(isolate, \
ArrayNoArgumentConstructor_##kind_camel##_##mode_camel), \
ArrayNoArgumentConstructorDescriptor(isolate))
if (override_mode == DONT_OVERRIDE && AllocationSite::ShouldTrack(kind)) {
DCHECK(IsSmiElementsKind(kind));
switch (kind) {
CASE(PACKED_SMI_ELEMENTS, PackedSmi, DontOverride);
CASE(HOLEY_SMI_ELEMENTS, HoleySmi, DontOverride);
default:
UNREACHABLE();
}
} else {
DCHECK(override_mode == DISABLE_ALLOCATION_SITES ||
!AllocationSite::ShouldTrack(kind));
switch (kind) {
CASE(PACKED_SMI_ELEMENTS, PackedSmi, DisableAllocationSites);
CASE(HOLEY_SMI_ELEMENTS, HoleySmi, DisableAllocationSites);
CASE(PACKED_ELEMENTS, Packed, DisableAllocationSites);
CASE(HOLEY_ELEMENTS, Holey, DisableAllocationSites);
CASE(PACKED_DOUBLE_ELEMENTS, PackedDouble, DisableAllocationSites);
CASE(HOLEY_DOUBLE_ELEMENTS, HoleyDouble, DisableAllocationSites);
default:
UNREACHABLE();
}
}
#undef CASE
}
// static
Callable CodeFactory::ArraySingleArgumentConstructor(
Isolate* isolate, ElementsKind kind,
AllocationSiteOverrideMode override_mode) {
ArraySingleArgumentConstructorStub stub(isolate, kind, override_mode);
return make_callable(stub);
#define CASE(kind_caps, kind_camel, mode_camel) \
case kind_caps: \
return Callable( \
BUILTIN_CODE( \
isolate, \
ArraySingleArgumentConstructor_##kind_camel##_##mode_camel), \
ArraySingleArgumentConstructorDescriptor(isolate))
if (override_mode == DONT_OVERRIDE && AllocationSite::ShouldTrack(kind)) {
DCHECK(IsSmiElementsKind(kind));
switch (kind) {
CASE(PACKED_SMI_ELEMENTS, PackedSmi, DontOverride);
CASE(HOLEY_SMI_ELEMENTS, HoleySmi, DontOverride);
default:
UNREACHABLE();
}
} else {
DCHECK(override_mode == DISABLE_ALLOCATION_SITES ||
!AllocationSite::ShouldTrack(kind));
switch (kind) {
CASE(PACKED_SMI_ELEMENTS, PackedSmi, DisableAllocationSites);
CASE(HOLEY_SMI_ELEMENTS, HoleySmi, DisableAllocationSites);
CASE(PACKED_ELEMENTS, Packed, DisableAllocationSites);
CASE(HOLEY_ELEMENTS, Holey, DisableAllocationSites);
CASE(PACKED_DOUBLE_ELEMENTS, PackedDouble, DisableAllocationSites);
CASE(HOLEY_DOUBLE_ELEMENTS, HoleyDouble, DisableAllocationSites);
default:
UNREACHABLE();
}
}
#undef CASE
}
// static
Callable CodeFactory::InternalArrayNoArgumentConstructor(Isolate* isolate,
ElementsKind kind) {
InternalArrayNoArgumentConstructorStub stub(isolate, kind);
return make_callable(stub);
switch (kind) {
case PACKED_ELEMENTS:
return Callable(
BUILTIN_CODE(isolate, InternalArrayNoArgumentConstructor_Packed),
ArrayNoArgumentConstructorDescriptor(isolate));
case HOLEY_ELEMENTS:
return Callable(
BUILTIN_CODE(isolate, InternalArrayNoArgumentConstructor_Holey),
ArrayNoArgumentConstructorDescriptor(isolate));
default:
UNREACHABLE();
}
}
// static
Callable CodeFactory::InternalArraySingleArgumentConstructor(
Isolate* isolate, ElementsKind kind) {
InternalArraySingleArgumentConstructorStub stub(isolate, kind);
return make_callable(stub);
switch (kind) {
case PACKED_ELEMENTS:
return Callable(
BUILTIN_CODE(isolate, InternalArraySingleArgumentConstructor_Packed),
ArraySingleArgumentConstructorDescriptor(isolate));
case HOLEY_ELEMENTS:
return Callable(
BUILTIN_CODE(isolate, InternalArraySingleArgumentConstructor_Holey),
ArraySingleArgumentConstructorDescriptor(isolate));
default:
UNREACHABLE();
}
}
// static
......
......@@ -15,6 +15,12 @@
namespace v8 {
namespace internal {
// For ArrayNoArgumentConstructor and ArraySingleArgumentConstructor.
enum AllocationSiteOverrideMode {
DONT_OVERRIDE,
DISABLE_ALLOCATION_SITES,
};
class V8_EXPORT_PRIVATE CodeFactory final {
public:
// CEntry has var-args semantics (all the arguments are passed on the
......
......@@ -459,169 +459,8 @@ void ProfileEntryHookStub::EntryHookTrampoline(intptr_t function,
}
void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
CommonArrayConstructorStub::GenerateStubsAheadOfTime(isolate);
StoreFastElementStub::GenerateAheadOfTime(isolate);
}
namespace {
void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
int to_index =
GetSequenceIndexFromFastElementsKind(TERMINAL_FAST_ELEMENTS_KIND);
for (int i = 0; i <= to_index; ++i) {
ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
CodeFactory::ArrayNoArgumentConstructor(isolate, kind, DONT_OVERRIDE);
CodeFactory::ArraySingleArgumentConstructor(isolate, kind, DONT_OVERRIDE);
if (AllocationSite::ShouldTrack(kind)) {
CodeFactory::ArrayNoArgumentConstructor(isolate, kind,
DISABLE_ALLOCATION_SITES);
CodeFactory::ArraySingleArgumentConstructor(isolate, kind,
DISABLE_ALLOCATION_SITES);
}
}
}
} // namespace
void CommonArrayConstructorStub::GenerateStubsAheadOfTime(Isolate* isolate) {
ArrayConstructorStubAheadOfTimeHelper(isolate);
ElementsKind kinds[2] = {PACKED_ELEMENTS, HOLEY_ELEMENTS};
for (int i = 0; i < 2; i++) {
CodeFactory::InternalArrayNoArgumentConstructor(isolate, kinds[i]);
CodeFactory::InternalArraySingleArgumentConstructor(isolate, kinds[i]);
}
}
TF_STUB(ArrayNoArgumentConstructorStub, CodeStubAssembler) {
ElementsKind elements_kind = stub->elements_kind();
Node* native_context = LoadObjectField(Parameter(Descriptor::kFunction),
JSFunction::kContextOffset);
bool track_allocation_site =
AllocationSite::ShouldTrack(elements_kind) &&
stub->override_mode() != DISABLE_ALLOCATION_SITES;
Node* allocation_site =
track_allocation_site ? Parameter(Descriptor::kAllocationSite) : nullptr;
Node* array_map = LoadJSArrayElementsMap(elements_kind, native_context);
Node* array =
AllocateJSArray(elements_kind, array_map,
IntPtrConstant(JSArray::kPreallocatedArrayElements),
SmiConstant(0), allocation_site);
Return(array);
}
TF_STUB(InternalArrayNoArgumentConstructorStub, CodeStubAssembler) {
Node* array_map = LoadObjectField(Parameter(Descriptor::kFunction),
JSFunction::kPrototypeOrInitialMapOffset);
Node* array = AllocateJSArray(
stub->elements_kind(), array_map,
IntPtrConstant(JSArray::kPreallocatedArrayElements), SmiConstant(0));
Return(array);
}
class ArrayConstructorAssembler : public CodeStubAssembler {
public:
typedef compiler::Node Node;
explicit ArrayConstructorAssembler(compiler::CodeAssemblerState* state)
: CodeStubAssembler(state) {}
void GenerateConstructor(Node* context, Node* array_function, Node* array_map,
Node* array_size, Node* allocation_site,
ElementsKind elements_kind, AllocationSiteMode mode);
};
void ArrayConstructorAssembler::GenerateConstructor(
Node* context, Node* array_function, Node* array_map, Node* array_size,
Node* allocation_site, ElementsKind elements_kind,
AllocationSiteMode mode) {
Label ok(this);
Label smi_size(this);
Label small_smi_size(this);
Label call_runtime(this, Label::kDeferred);
Branch(TaggedIsSmi(array_size), &smi_size, &call_runtime);
BIND(&smi_size);
if (IsFastPackedElementsKind(elements_kind)) {
Label abort(this, Label::kDeferred);
Branch(SmiEqual(CAST(array_size), SmiConstant(0)), &small_smi_size, &abort);
BIND(&abort);
Node* reason = SmiConstant(AbortReason::kAllocatingNonEmptyPackedArray);
TailCallRuntime(Runtime::kAbort, context, reason);
} else {
int element_size =
IsDoubleElementsKind(elements_kind) ? kDoubleSize : kPointerSize;
int max_fast_elements =
(kMaxRegularHeapObjectSize - FixedArray::kHeaderSize - JSArray::kSize -
AllocationMemento::kSize) /
element_size;
Branch(SmiAboveOrEqual(CAST(array_size), SmiConstant(max_fast_elements)),
&call_runtime, &small_smi_size);
}
BIND(&small_smi_size);
{
Node* array = AllocateJSArray(
elements_kind, array_map, array_size, array_size,
mode == DONT_TRACK_ALLOCATION_SITE ? nullptr : allocation_site,
CodeStubAssembler::SMI_PARAMETERS);
Return(array);
}
BIND(&call_runtime);
{
TailCallRuntime(Runtime::kNewArray, context, array_function, array_size,
array_function, allocation_site);
}
}
TF_STUB(ArraySingleArgumentConstructorStub, ArrayConstructorAssembler) {
ElementsKind elements_kind = stub->elements_kind();
Node* context = Parameter(Descriptor::kContext);
Node* function = Parameter(Descriptor::kFunction);
Node* native_context = LoadObjectField(function, JSFunction::kContextOffset);
Node* array_map = LoadJSArrayElementsMap(elements_kind, native_context);
AllocationSiteMode mode = DONT_TRACK_ALLOCATION_SITE;
if (stub->override_mode() == DONT_OVERRIDE) {
mode = AllocationSite::ShouldTrack(elements_kind)
? TRACK_ALLOCATION_SITE
: DONT_TRACK_ALLOCATION_SITE;
}
Node* array_size = Parameter(Descriptor::kArraySizeSmiParameter);
Node* allocation_site = Parameter(Descriptor::kAllocationSite);
GenerateConstructor(context, function, array_map, array_size, allocation_site,
elements_kind, mode);
}
TF_STUB(InternalArraySingleArgumentConstructorStub, ArrayConstructorAssembler) {
Node* context = Parameter(Descriptor::kContext);
Node* function = Parameter(Descriptor::kFunction);
Node* array_map =
LoadObjectField(function, JSFunction::kPrototypeOrInitialMapOffset);
Node* array_size = Parameter(Descriptor::kArraySizeSmiParameter);
Node* allocation_site = UndefinedConstant();
GenerateConstructor(context, function, array_map, array_size, allocation_site,
stub->elements_kind(), DONT_TRACK_ALLOCATION_SITE);
}
CommonArrayConstructorStub::CommonArrayConstructorStub(
Isolate* isolate, ElementsKind kind,
AllocationSiteOverrideMode override_mode)
: TurboFanCodeStub(isolate) {
// It only makes sense to override local allocation site behavior
// if there is a difference between the global allocation site policy
// for an ElementsKind and the desired usage of the stub.
DCHECK(override_mode != DISABLE_ALLOCATION_SITES ||
AllocationSite::ShouldTrack(kind));
set_sub_minor_key(ElementsKindBits::encode(kind) |
AllocationSiteOverrideModeBits::encode(override_mode));
}
} // namespace internal
} // namespace v8
......@@ -27,10 +27,6 @@ class CodeAssemblerState;
/* --- TurboFanCodeStubs --- */ \
V(StoreSlowElement) \
V(StoreInArrayLiteralSlow) \
V(ArrayNoArgumentConstructor) \
V(ArraySingleArgumentConstructor) \
V(InternalArrayNoArgumentConstructor) \
V(InternalArraySingleArgumentConstructor) \
V(ElementsTransitionAndStore) \
V(KeyedLoadSloppyArguments) \
V(KeyedStoreSloppyArguments) \
......@@ -437,12 +433,6 @@ class LoadIndexedInterceptorStub : public TurboFanCodeStub {
DEFINE_TURBOFAN_CODE_STUB(LoadIndexedInterceptor, TurboFanCodeStub);
};
enum AllocationSiteOverrideMode {
DONT_OVERRIDE,
DISABLE_ALLOCATION_SITES,
LAST_ALLOCATION_SITE_OVERRIDE_MODE = DISABLE_ALLOCATION_SITES
};
// TODO(jgruber): Convert this stub into a builtin.
class KeyedLoadSloppyArgumentsStub : public TurboFanCodeStub {
public:
......@@ -592,110 +582,6 @@ class StoreFastElementStub : public TurboFanCodeStub {
DEFINE_TURBOFAN_CODE_STUB(StoreFastElement, TurboFanCodeStub);
};
class CommonArrayConstructorStub : public TurboFanCodeStub {
protected:
CommonArrayConstructorStub(Isolate* isolate, ElementsKind kind,
AllocationSiteOverrideMode override_mode);
void set_sub_minor_key(uint32_t key) { minor_key_ = key; }
uint32_t sub_minor_key() const { return minor_key_; }
CommonArrayConstructorStub(uint32_t key, Isolate* isolate)
: TurboFanCodeStub(key, isolate) {}
public:
ElementsKind elements_kind() const {
return ElementsKindBits::decode(sub_minor_key());
}
AllocationSiteOverrideMode override_mode() const {
return AllocationSiteOverrideModeBits::decode(sub_minor_key());
}
static void GenerateStubsAheadOfTime(Isolate* isolate);
private:
// Ensure data fits within available bits.
STATIC_ASSERT(LAST_ALLOCATION_SITE_OVERRIDE_MODE == 1);
class ElementsKindBits : public BitField<ElementsKind, 0, 8> {};
class AllocationSiteOverrideModeBits
: public BitField<AllocationSiteOverrideMode, 8, 1> {}; // NOLINT
};
class ArrayNoArgumentConstructorStub : public CommonArrayConstructorStub {
private:
ArrayNoArgumentConstructorStub(
Isolate* isolate, ElementsKind kind,
AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
: CommonArrayConstructorStub(isolate, kind, override_mode) {}
friend class CodeFactory;
void PrintName(std::ostream& os) const override { // NOLINT
os << "ArrayNoArgumentConstructorStub";
}
DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayNoArgumentConstructor);
DEFINE_TURBOFAN_CODE_STUB(ArrayNoArgumentConstructor,
CommonArrayConstructorStub);
};
class InternalArrayNoArgumentConstructorStub
: public CommonArrayConstructorStub {
private:
InternalArrayNoArgumentConstructorStub(Isolate* isolate, ElementsKind kind)
: CommonArrayConstructorStub(isolate, kind, DONT_OVERRIDE) {}
friend class CodeFactory;
void PrintName(std::ostream& os) const override { // NOLINT
os << "InternalArrayNoArgumentConstructorStub";
}
DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayNoArgumentConstructor);
DEFINE_TURBOFAN_CODE_STUB(InternalArrayNoArgumentConstructor,
CommonArrayConstructorStub);
};
class ArraySingleArgumentConstructorStub : public CommonArrayConstructorStub {
private:
ArraySingleArgumentConstructorStub(
Isolate* isolate, ElementsKind kind,
AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
: CommonArrayConstructorStub(isolate, kind, override_mode) {}
friend class CodeFactory;
void PrintName(std::ostream& os) const override { // NOLINT
os << "ArraySingleArgumentConstructorStub";
}
DEFINE_CALL_INTERFACE_DESCRIPTOR(ArraySingleArgumentConstructor);
DEFINE_TURBOFAN_CODE_STUB(ArraySingleArgumentConstructor,
CommonArrayConstructorStub);
};
class InternalArraySingleArgumentConstructorStub
: public CommonArrayConstructorStub {
private:
InternalArraySingleArgumentConstructorStub(Isolate* isolate,
ElementsKind kind)
: CommonArrayConstructorStub(isolate, kind, DONT_OVERRIDE) {}
friend class CodeFactory;
void PrintName(std::ostream& os) const override { // NOLINT
os << "InternalArraySingleArgumentConstructorStub";
}
DEFINE_CALL_INTERFACE_DESCRIPTOR(ArraySingleArgumentConstructor);
DEFINE_TURBOFAN_CODE_STUB(InternalArraySingleArgumentConstructor,
CommonArrayConstructorStub);
};
class StoreSlowElementStub : public TurboFanCodeStub {
public:
StoreSlowElementStub(Isolate* isolate, KeyedAccessStoreMode mode)
......
......@@ -2441,12 +2441,8 @@ TEST(CheckCodeNames) {
const v8::HeapSnapshot* snapshot = heap_profiler->TakeHeapSnapshot();
CHECK(ValidateSnapshot(snapshot));
const char* stub_path[] = {
"::(GC roots)",
"::(Strong roots)",
"code_stubs::",
"::(ArraySingleArgumentConstructorStub code)"
};
const char* stub_path[] = {"::(GC roots)", "::(Strong roots)",
"code_stubs::", "::(StoreFastElementStub code)"};
const v8::HeapGraphNode* node = GetNodeByPath(
env->GetIsolate(), snapshot, stub_path, arraysize(stub_path));
CHECK(node);
......
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