[stubs]: Implement ArrayNoArgumentConstructor as a TF stub

Review-Url: https://codereview.chromium.org/1903723003
Cr-Commit-Position: refs/heads/master@{#35963}
This commit is contained in:
danno 2016-05-03 00:58:58 -07:00 committed by Commit bot
parent d8967c5564
commit fa570e55b6
20 changed files with 291 additions and 63 deletions

View File

@ -55,12 +55,6 @@ static void InitializeInternalArrayConstructorDescriptor(
}
void ArrayNoArgumentConstructorStub::InitializeDescriptor(
CodeStubDescriptor* descriptor) {
InitializeArrayConstructorDescriptor(isolate(), descriptor, 0);
}
void ArraySingleArgumentConstructorStub::InitializeDescriptor(
CodeStubDescriptor* descriptor) {
InitializeArrayConstructorDescriptor(isolate(), descriptor, 1);

View File

@ -247,6 +247,16 @@ void AllocateHeapNumberDescriptor::InitializePlatformSpecific(
SIMD128_TYPES(SIMD128_ALLOC_DESC)
#undef SIMD128_ALLOC_DESC
void ArrayNoArgumentConstructorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// register state
// r0 -- number of arguments
// r1 -- function
// r2 -- allocation site with elements kind
Register registers[] = {r1, r2, r0};
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
}
void ArrayConstructorConstantArgCountDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// register state

View File

@ -43,12 +43,6 @@ static void InitializeArrayConstructorDescriptor(
}
void ArrayNoArgumentConstructorStub::InitializeDescriptor(
CodeStubDescriptor* descriptor) {
InitializeArrayConstructorDescriptor(isolate(), descriptor, 0);
}
void ArraySingleArgumentConstructorStub::InitializeDescriptor(
CodeStubDescriptor* descriptor) {
InitializeArrayConstructorDescriptor(isolate(), descriptor, 1);

View File

@ -272,6 +272,16 @@ void AllocateHeapNumberDescriptor::InitializePlatformSpecific(
SIMD128_TYPES(SIMD128_ALLOC_DESC)
#undef SIMD128_ALLOC_DESC
void ArrayNoArgumentConstructorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// register state
// x1: function
// x2: allocation site with elements kind
// x0: number of arguments to the constructor function
Register registers[] = {x1, x2, x0};
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
}
void ArrayConstructorConstantArgCountDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// x1: function

View File

@ -238,9 +238,7 @@ Node* CodeStubAssembler::Float64Trunc(Node* x) {
}
Node* CodeStubAssembler::SmiFromWord32(Node* value) {
if (Is64()) {
value = ChangeInt32ToInt64(value);
}
value = ChangeInt32ToIntPtr(value);
return WordShl(value, SmiShiftBitsConstant());
}
@ -520,9 +518,7 @@ Node* CodeStubAssembler::LoadFixedArrayElementInt32Index(
Node* object, Node* index, int additional_offset) {
Node* header_size = IntPtrConstant(additional_offset +
FixedArray::kHeaderSize - kHeapObjectTag);
if (Is64()) {
index = ChangeInt32ToInt64(index);
}
index = ChangeInt32ToIntPtr(index);
Node* scaled_index = WordShl(index, IntPtrConstant(kPointerSizeLog2));
Node* offset = IntPtrAdd(scaled_index, header_size);
return Load(MachineType::AnyTagged(), object, offset);
@ -555,6 +551,11 @@ Node* CodeStubAssembler::LoadFixedArrayElementConstantIndex(Node* object,
return Load(MachineType::AnyTagged(), object, offset);
}
Node* CodeStubAssembler::LoadNativeContext(Node* context) {
return LoadFixedArrayElementConstantIndex(context,
Context::NATIVE_CONTEXT_INDEX);
}
Node* CodeStubAssembler::StoreHeapNumberValue(Node* object, Node* value) {
return StoreNoWriteBarrier(
MachineRepresentation::kFloat64, object,
@ -582,6 +583,7 @@ Node* CodeStubAssembler::StoreMapNoWriteBarrier(Node* object, Node* map) {
Node* CodeStubAssembler::StoreFixedArrayElementNoWriteBarrier(Node* object,
Node* index,
Node* value) {
index = ChangeInt32ToIntPtr(index);
Node* offset =
IntPtrAdd(WordShl(index, IntPtrConstant(kPointerSizeLog2)),
IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag));
@ -592,15 +594,50 @@ Node* CodeStubAssembler::StoreFixedArrayElementNoWriteBarrier(Node* object,
Node* CodeStubAssembler::StoreFixedArrayElementInt32Index(Node* object,
Node* index,
Node* value) {
if (Is64()) {
index = ChangeInt32ToInt64(index);
}
index = ChangeInt32ToIntPtr(index);
Node* offset =
IntPtrAdd(WordShl(index, IntPtrConstant(kPointerSizeLog2)),
IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag));
return Store(MachineRepresentation::kTagged, object, offset, value);
}
Node* CodeStubAssembler::StoreFixedDoubleArrayElementInt32Index(Node* object,
Node* index,
Node* value) {
index = ChangeInt32ToIntPtr(index);
Node* offset =
IntPtrAdd(WordShl(index, IntPtrConstant(kPointerSizeLog2)),
IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag));
return StoreNoWriteBarrier(MachineRepresentation::kFloat64, object, offset,
value);
}
Node* CodeStubAssembler::StoreFixedArrayElementInt32Index(Node* object,
int index,
Node* value) {
Node* offset = IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag +
index * kPointerSize);
return Store(MachineRepresentation::kTagged, object, offset, value);
}
Node* CodeStubAssembler::StoreFixedArrayElementNoWriteBarrier(Node* object,
int index,
Node* value) {
Node* offset = IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag +
index * kPointerSize);
return StoreNoWriteBarrier(MachineRepresentation::kTagged, object, offset,
value);
}
Node* CodeStubAssembler::StoreFixedDoubleArrayElementInt32Index(Node* object,
int index,
Node* value) {
Node* offset = IntPtrConstant(FixedDoubleArray::kHeaderSize - kHeapObjectTag +
index * kDoubleSize);
return StoreNoWriteBarrier(MachineRepresentation::kFloat64, object, offset,
value);
}
Node* CodeStubAssembler::AllocateHeapNumber() {
Node* result = Allocate(HeapNumber::kSize, kNone);
StoreMapNoWriteBarrier(result, HeapNumberMapConstant());
@ -633,6 +670,85 @@ Node* CodeStubAssembler::AllocateSeqTwoByteString(int length) {
return result;
}
Node* CodeStubAssembler::AllocateJSArray(ElementsKind kind,
Node* native_context, int capacity,
int length,
compiler::Node* allocation_site) {
bool is_double = IsFastDoubleElementsKind(kind);
int element_size = is_double ? kDoubleSize : kPointerSize;
int total_size =
JSArray::kSize + FixedArray::kHeaderSize + element_size * capacity;
int elements_offset = JSArray::kSize;
if (allocation_site != nullptr) {
total_size += AllocationMemento::kSize;
elements_offset += AllocationMemento::kSize;
}
// Allocate both array and elements object, and initialize the JSArray.
Heap* heap = isolate()->heap();
Node* array = Allocate(total_size);
Node* array_map = LoadFixedArrayElementConstantIndex(
native_context, Context::ArrayMapIndex(kind));
StoreMapNoWriteBarrier(array, array_map);
Node* empty_properties =
HeapConstant(Handle<HeapObject>(heap->empty_fixed_array()));
StoreObjectFieldNoWriteBarrier(array, JSArray::kPropertiesOffset,
empty_properties);
StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset,
SmiConstant(Smi::FromInt(length)));
if (allocation_site != nullptr) {
InitializeAllocationMemento(array, JSArray::kSize, allocation_site);
}
// Setup elements object.
Node* elements = InnerAllocate(array, elements_offset);
StoreObjectFieldNoWriteBarrier(array, JSArray::kElementsOffset, elements);
Handle<Map> elements_map(is_double ? heap->fixed_double_array_map()
: heap->fixed_array_map());
StoreMapNoWriteBarrier(elements, HeapConstant(elements_map));
StoreObjectFieldNoWriteBarrier(elements, FixedArray::kLengthOffset,
SmiConstant(Smi::FromInt(capacity)));
Node* double_hole = Float64Constant(bit_cast<double>(kHoleNanInt64));
Node* hole = HeapConstant(Handle<HeapObject>(heap->the_hole_value()));
if (capacity <= kElementLoopUnrollThreshold) {
for (int i = 0; i < capacity; ++i) {
if (is_double) {
StoreFixedDoubleArrayElementInt32Index(elements, i, double_hole);
} else {
StoreFixedArrayElementNoWriteBarrier(elements, i, hole);
}
}
} else {
// TODO(danno): Add a loop for initialization
UNIMPLEMENTED();
}
return array;
}
void CodeStubAssembler::InitializeAllocationMemento(
compiler::Node* base_allocation, int base_allocation_size,
compiler::Node* allocation_site) {
StoreObjectFieldNoWriteBarrier(
base_allocation, AllocationMemento::kMapOffset + base_allocation_size,
HeapConstant(Handle<Map>(isolate()->heap()->allocation_memento_map())));
StoreObjectFieldNoWriteBarrier(
base_allocation,
AllocationMemento::kAllocationSiteOffset + base_allocation_size,
allocation_site);
if (FLAG_allocation_site_pretenuring) {
Node* count = LoadObjectField(allocation_site,
AllocationSite::kPretenureCreateCountOffset);
Node* incremented_count = IntPtrAdd(count, SmiConstant(Smi::FromInt(1)));
StoreObjectFieldNoWriteBarrier(allocation_site,
AllocationSite::kPretenureCreateCountOffset,
incremented_count);
}
}
Node* CodeStubAssembler::TruncateTaggedToFloat64(Node* context, Node* value) {
// We might need to loop once due to ToNumber conversion.
Variable var_value(this, MachineRepresentation::kTagged),

View File

@ -139,6 +139,9 @@ class CodeStubAssembler : public compiler::CodeAssembler {
compiler::Node* LoadFixedArrayElementConstantIndex(compiler::Node* object,
int index);
// Context manipulation
compiler::Node* LoadNativeContext(compiler::Node* context);
// Store the floating point value of a HeapNumber.
compiler::Node* StoreHeapNumberValue(compiler::Node* object,
compiler::Node* value);
@ -158,6 +161,18 @@ class CodeStubAssembler : public compiler::CodeAssembler {
compiler::Node* StoreFixedArrayElementNoWriteBarrier(compiler::Node* object,
compiler::Node* index,
compiler::Node* value);
compiler::Node* StoreFixedDoubleArrayElementInt32Index(compiler::Node* object,
compiler::Node* index,
compiler::Node* value);
compiler::Node* StoreFixedArrayElementInt32Index(compiler::Node* object,
int index,
compiler::Node* value);
compiler::Node* StoreFixedArrayElementNoWriteBarrier(compiler::Node* object,
int index,
compiler::Node* value);
compiler::Node* StoreFixedDoubleArrayElementInt32Index(compiler::Node* object,
int index,
compiler::Node* value);
// Allocate a HeapNumber without initializing its value.
compiler::Node* AllocateHeapNumber();
@ -167,6 +182,16 @@ class CodeStubAssembler : public compiler::CodeAssembler {
compiler::Node* AllocateSeqOneByteString(int length);
// Allocate a SeqTwoByteString with the given length.
compiler::Node* AllocateSeqTwoByteString(int length);
// Allocated an JSArray
compiler::Node* AllocateJSArray(ElementsKind kind,
compiler::Node* native_context, int capacity,
int length,
compiler::Node* allocation_site = nullptr);
// Allocation site manipulation
void InitializeAllocationMemento(compiler::Node* base_allocation,
int base_allocation_size,
compiler::Node* allocation_site);
compiler::Node* TruncateTaggedToFloat64(compiler::Node* context,
compiler::Node* value);
@ -211,6 +236,8 @@ class CodeStubAssembler : public compiler::CodeAssembler {
AllocationFlags flags,
compiler::Node* top_adddress,
compiler::Node* limit_address);
static const int kElementLoopUnrollThreshold = 8;
};
} // namespace internal

View File

@ -1408,12 +1408,6 @@ HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() {
return BuildArrayConstructor(kind, override_mode, NONE);
}
Handle<Code> ArrayNoArgumentConstructorStub::GenerateCode() {
return DoGenerateCode(this);
}
template <>
HValue* CodeStubGraphBuilder<ArraySingleArgumentConstructorStub>::
BuildCodeStub() {

View File

@ -4250,6 +4250,26 @@ void ProfileEntryHookStub::EntryHookTrampoline(intptr_t function,
entry_hook(function, stack_pointer);
}
void ArrayNoArgumentConstructorStub::GenerateAssembly(
CodeStubAssembler* assembler) const {
typedef compiler::Node Node;
Node* native_context = assembler->LoadObjectField(
assembler->Parameter(
ArrayNoArgumentConstructorDescriptor::kFunctionIndex),
JSFunction::kContextOffset);
bool track_allocation_site =
AllocationSite::GetMode(elements_kind()) == TRACK_ALLOCATION_SITE &&
override_mode() != DISABLE_ALLOCATION_SITES;
Node* allocation_site =
track_allocation_site
? assembler->Parameter(
ArrayNoArgumentConstructorDescriptor::kAllocationSiteIndex)
: nullptr;
Node* array = assembler->AllocateJSArray(elements_kind(), native_context,
JSArray::kPreallocatedArrayElements,
0, allocation_site);
assembler->Return(array);
}
ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate)
: PlatformCodeStub(isolate) {

View File

@ -2801,26 +2801,48 @@ class ArrayConstructorStubBase : public HydrogenCodeStub {
DEFINE_CODE_STUB_BASE(ArrayConstructorStubBase, HydrogenCodeStub);
};
class ArrayNoArgumentConstructorStub : public ArrayConstructorStubBase {
class ArrayNoArgumentConstructorStub : public TurboFanCodeStub {
public:
ArrayNoArgumentConstructorStub(
Isolate* isolate,
ElementsKind kind,
Isolate* isolate, ElementsKind kind,
AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
: ArrayConstructorStubBase(isolate, kind, 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::GetMode(kind) == TRACK_ALLOCATION_SITE);
set_sub_minor_key(ElementsKindBits::encode(kind) |
AllocationSiteOverrideModeBits::encode(override_mode));
}
void set_sub_minor_key(uint32_t key) { minor_key_ = key; }
uint32_t sub_minor_key() const { return minor_key_; }
ElementsKind elements_kind() const {
return ElementsKindBits::decode(sub_minor_key());
}
AllocationSiteOverrideMode override_mode() const {
return AllocationSiteOverrideModeBits::decode(sub_minor_key());
}
private:
void PrintName(std::ostream& os) const override { // NOLINT
BasePrintName(os, "ArrayNoArgumentConstructorStub");
os << "ArrayNoArgumentConstructorStub";
}
DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayConstructorConstantArgCount);
DEFINE_HYDROGEN_CODE_STUB(ArrayNoArgumentConstructor,
ArrayConstructorStubBase);
};
// 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
DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayNoArgumentConstructor);
DEFINE_TURBOFAN_CODE_STUB(ArrayNoArgumentConstructor, TurboFanCodeStub);
};
class ArraySingleArgumentConstructorStub : public ArrayConstructorStubBase {
public:

View File

@ -2722,8 +2722,6 @@ void Heap::CreateInitialObjects() {
#undef SYMBOL_INIT
}
CreateFixedStubs();
// Allocate the dictionary of intrinsic function names.
Handle<NameDictionary> intrinsic_names =
NameDictionary::New(isolate(), Runtime::kNumFunctions, TENURED);
@ -2865,6 +2863,8 @@ void Heap::CreateInitialObjects() {
// Initialize compilation cache.
isolate_->compilation_cache()->Clear();
CreateFixedStubs();
}

View File

@ -62,12 +62,6 @@ static void InitializeInternalArrayConstructorDescriptor(
}
void ArrayNoArgumentConstructorStub::InitializeDescriptor(
CodeStubDescriptor* descriptor) {
InitializeArrayConstructorDescriptor(isolate(), descriptor, 0);
}
void ArraySingleArgumentConstructorStub::InitializeDescriptor(
CodeStubDescriptor* descriptor) {
InitializeArrayConstructorDescriptor(isolate(), descriptor, 1);

View File

@ -251,6 +251,16 @@ void AllocateHeapNumberDescriptor::InitializePlatformSpecific(
SIMD128_TYPES(SIMD128_ALLOC_DESC)
#undef SIMD128_ALLOC_DESC
void ArrayNoArgumentConstructorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// register state
// eax -- number of arguments
// edi -- function
// ebx -- allocation site with elements kind
Register registers[] = {edi, ebx, eax};
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
}
void ArrayConstructorConstantArgCountDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// register state

View File

@ -439,6 +439,19 @@ FunctionType* CallFunctionWithFeedbackAndVectorDescriptor::
return function;
}
FunctionType*
ArrayNoArgumentConstructorDescriptor::BuildCallInterfaceDescriptorFunctionType(
Isolate* isolate, int paramater_count) {
Zone* zone = isolate->interface_descriptor_zone();
FunctionType* function =
Type::Function(AnyTagged(zone), Type::Undefined(), 4, zone)->AsFunction();
function->InitParameter(0, Type::Receiver()); // JSFunction
function->InitParameter(1, AnyTagged(zone));
function->InitParameter(2, UntaggedIntegral32(zone));
function->InitParameter(3, AnyTagged(zone));
return function;
}
FunctionType*
ArrayConstructorDescriptor::BuildCallInterfaceDescriptorFunctionType(
Isolate* isolate, int paramater_count) {

View File

@ -58,6 +58,7 @@ class PlatformInterfaceDescriptor;
V(AllocateInt8x16) \
V(AllocateUint8x16) \
V(AllocateBool8x16) \
V(ArrayNoArgumentConstructor) \
V(ArrayConstructorConstantArgCount) \
V(ArrayConstructor) \
V(InternalArrayConstructorConstantArgCount) \
@ -577,6 +578,17 @@ class AllocateMutableHeapNumberDescriptor : public CallInterfaceDescriptor {
CallInterfaceDescriptor)
};
class ArrayNoArgumentConstructorDescriptor : public CallInterfaceDescriptor {
public:
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(
ArrayNoArgumentConstructorDescriptor, CallInterfaceDescriptor)
enum ParameterIndices {
kFunctionIndex,
kAllocationSiteIndex,
kArgumentCountIndex,
kContextIndex
};
};
class ArrayConstructorConstantArgCountDescriptor
: public CallInterfaceDescriptor {

View File

@ -54,12 +54,6 @@ static void InitializeInternalArrayConstructorDescriptor(
}
void ArrayNoArgumentConstructorStub::InitializeDescriptor(
CodeStubDescriptor* descriptor) {
InitializeArrayConstructorDescriptor(isolate(), descriptor, 0);
}
void ArraySingleArgumentConstructorStub::InitializeDescriptor(
CodeStubDescriptor* descriptor) {
InitializeArrayConstructorDescriptor(isolate(), descriptor, 1);

View File

@ -246,6 +246,16 @@ void AllocateHeapNumberDescriptor::InitializePlatformSpecific(
SIMD128_TYPES(SIMD128_ALLOC_DESC)
#undef SIMD128_ALLOC_DESC
void ArrayNoArgumentConstructorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// register state
// a0 -- number of arguments
// a1 -- function
// a2 -- allocation site with elements kind
Register registers[] = {a1, a2, a0};
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
}
void ArrayConstructorConstantArgCountDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// register state

View File

@ -53,12 +53,6 @@ static void InitializeInternalArrayConstructorDescriptor(
}
void ArrayNoArgumentConstructorStub::InitializeDescriptor(
CodeStubDescriptor* descriptor) {
InitializeArrayConstructorDescriptor(isolate(), descriptor, 0);
}
void ArraySingleArgumentConstructorStub::InitializeDescriptor(
CodeStubDescriptor* descriptor) {
InitializeArrayConstructorDescriptor(isolate(), descriptor, 1);

View File

@ -246,6 +246,16 @@ void AllocateHeapNumberDescriptor::InitializePlatformSpecific(
SIMD128_TYPES(SIMD128_ALLOC_DESC)
#undef SIMD128_ALLOC_DESC
void ArrayNoArgumentConstructorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// register state
// a0 -- number of arguments
// a1 -- function
// a2 -- allocation site with elements kind
Register registers[] = {a1, a2, a0};
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
}
void ArrayConstructorConstantArgCountDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// register state

View File

@ -53,12 +53,6 @@ static void InitializeInternalArrayConstructorDescriptor(
}
void ArrayNoArgumentConstructorStub::InitializeDescriptor(
CodeStubDescriptor* descriptor) {
InitializeArrayConstructorDescriptor(isolate(), descriptor, 0);
}
void ArraySingleArgumentConstructorStub::InitializeDescriptor(
CodeStubDescriptor* descriptor) {
InitializeArrayConstructorDescriptor(isolate(), descriptor, 1);

View File

@ -242,6 +242,16 @@ void AllocateHeapNumberDescriptor::InitializePlatformSpecific(
SIMD128_TYPES(SIMD128_ALLOC_DESC)
#undef SIMD128_ALLOC_DESC
void ArrayNoArgumentConstructorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// register state
// rax -- number of arguments
// rdi -- function
// rbx -- allocation site with elements kind
Register registers[] = {rdi, rbx, rax};
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
}
void ArrayConstructorConstantArgCountDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// register state