[stubs] Remove N-argument Hydrogen-based Array constructor stub
Instead, always tail call to the runtime. Also, cleanup the various versions of the runtime call that is used for Array construction fallback. There can be only one. BUG=chromium:608675 LOG=N Review-Url: https://codereview.chromium.org/2024253002 Cr-Commit-Position: refs/heads/master@{#36888}
This commit is contained in:
parent
75aada429e
commit
c8ac0d8693
@ -22,45 +22,17 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
#define __ ACCESS_MASM(masm)
|
||||
|
||||
static void InitializeArrayConstructorDescriptor(
|
||||
Isolate* isolate, CodeStubDescriptor* descriptor,
|
||||
int constant_stack_parameter_count) {
|
||||
Address deopt_handler = Runtime::FunctionForId(
|
||||
Runtime::kArrayConstructor)->entry;
|
||||
|
||||
if (constant_stack_parameter_count == 0) {
|
||||
descriptor->Initialize(deopt_handler, constant_stack_parameter_count,
|
||||
JS_FUNCTION_STUB_MODE);
|
||||
} else {
|
||||
descriptor->Initialize(r0, deopt_handler, constant_stack_parameter_count,
|
||||
JS_FUNCTION_STUB_MODE);
|
||||
}
|
||||
void ArrayNArgumentsConstructorStub::Generate(MacroAssembler* masm) {
|
||||
__ lsl(r5, r0, Operand(kPointerSizeLog2));
|
||||
__ str(r1, MemOperand(sp, r5));
|
||||
__ Push(r1);
|
||||
__ Push(r2);
|
||||
__ add(r0, r0, Operand(3));
|
||||
__ TailCallRuntime(Runtime::kNewArray);
|
||||
}
|
||||
|
||||
|
||||
static void InitializeInternalArrayConstructorDescriptor(
|
||||
Isolate* isolate, CodeStubDescriptor* descriptor,
|
||||
int constant_stack_parameter_count) {
|
||||
Address deopt_handler = Runtime::FunctionForId(
|
||||
Runtime::kInternalArrayConstructor)->entry;
|
||||
|
||||
if (constant_stack_parameter_count == 0) {
|
||||
descriptor->Initialize(deopt_handler, constant_stack_parameter_count,
|
||||
JS_FUNCTION_STUB_MODE);
|
||||
} else {
|
||||
descriptor->Initialize(r0, deopt_handler, constant_stack_parameter_count,
|
||||
JS_FUNCTION_STUB_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ArrayNArgumentsConstructorStub::InitializeDescriptor(
|
||||
CodeStubDescriptor* descriptor) {
|
||||
InitializeArrayConstructorDescriptor(isolate(), descriptor, -1);
|
||||
}
|
||||
|
||||
|
||||
void FastArrayPushStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
|
||||
Address deopt_handler = Runtime::FunctionForId(Runtime::kArrayPush)->entry;
|
||||
descriptor->Initialize(r0, deopt_handler, -1, JS_FUNCTION_STUB_MODE);
|
||||
@ -72,14 +44,6 @@ void FastFunctionBindStub::InitializeDescriptor(
|
||||
descriptor->Initialize(r0, deopt_handler, -1, JS_FUNCTION_STUB_MODE);
|
||||
}
|
||||
|
||||
void InternalArrayNArgumentsConstructorStub::InitializeDescriptor(
|
||||
CodeStubDescriptor* descriptor) {
|
||||
InitializeInternalArrayConstructorDescriptor(isolate(), descriptor, -1);
|
||||
}
|
||||
|
||||
|
||||
#define __ ACCESS_MASM(masm)
|
||||
|
||||
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
||||
Condition cond);
|
||||
static void EmitSmiNonsmiComparison(MacroAssembler* masm,
|
||||
@ -936,7 +900,7 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
|
||||
CEntryStub::GenerateAheadOfTime(isolate);
|
||||
StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate);
|
||||
StubFailureTrampolineStub::GenerateAheadOfTime(isolate);
|
||||
ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
|
||||
CommonArrayConstructorStub::GenerateStubsAheadOfTime(isolate);
|
||||
CreateAllocationSiteStub::GenerateAheadOfTime(isolate);
|
||||
CreateWeakCellStub::GenerateAheadOfTime(isolate);
|
||||
BinaryOpICStub::GenerateAheadOfTime(isolate);
|
||||
@ -4147,19 +4111,13 @@ static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) {
|
||||
void CommonArrayConstructorStub::GenerateStubsAheadOfTime(Isolate* isolate) {
|
||||
ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>(
|
||||
isolate);
|
||||
ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>(
|
||||
isolate);
|
||||
ArrayConstructorStubAheadOfTimeHelper<ArrayNArgumentsConstructorStub>(
|
||||
isolate);
|
||||
}
|
||||
|
||||
|
||||
void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
|
||||
Isolate* isolate) {
|
||||
ArrayNArgumentsConstructorStub stub(isolate);
|
||||
stub.GetCode();
|
||||
ElementsKind kinds[2] = { FAST_ELEMENTS, FAST_HOLEY_ELEMENTS };
|
||||
for (int i = 0; i < 2; i++) {
|
||||
// For internal arrays we only need a few things
|
||||
@ -4167,8 +4125,6 @@ void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
|
||||
stubh1.GetCode();
|
||||
InternalArraySingleArgumentConstructorStub stubh2(isolate, kinds[i]);
|
||||
stubh2.GetCode();
|
||||
InternalArrayNArgumentsConstructorStub stubh3(isolate, kinds[i]);
|
||||
stubh3.GetCode();
|
||||
}
|
||||
}
|
||||
|
||||
@ -4188,13 +4144,15 @@ void ArrayConstructorStub::GenerateDispatchToArrayStub(
|
||||
CreateArrayDispatchOneArgument(masm, mode);
|
||||
|
||||
__ bind(¬_one_case);
|
||||
CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
|
||||
ArrayNArgumentsConstructorStub stub(masm->isolate());
|
||||
__ TailCallStub(&stub);
|
||||
} else if (argument_count() == NONE) {
|
||||
CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
|
||||
} else if (argument_count() == ONE) {
|
||||
CreateArrayDispatchOneArgument(masm, mode);
|
||||
} else if (argument_count() == MORE_THAN_ONE) {
|
||||
CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
|
||||
ArrayNArgumentsConstructorStub stub(masm->isolate());
|
||||
__ TailCallStub(&stub);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -4276,7 +4234,7 @@ void InternalArrayConstructorStub::GenerateCase(
|
||||
InternalArrayNoArgumentConstructorStub stub0(isolate(), kind);
|
||||
__ TailCallStub(&stub0, lo);
|
||||
|
||||
InternalArrayNArgumentsConstructorStub stubN(isolate(), kind);
|
||||
ArrayNArgumentsConstructorStub stubN(isolate());
|
||||
__ TailCallStub(&stubN, hi);
|
||||
|
||||
if (IsFastPackedElementsKind(kind)) {
|
||||
|
@ -271,7 +271,7 @@ void ArraySingleArgumentConstructorDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
|
||||
}
|
||||
|
||||
void ArrayConstructorDescriptor::InitializePlatformSpecific(
|
||||
void ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// stack param count needs (constructor pointer, and single argument)
|
||||
Register registers[] = {r1, r2, r0};
|
||||
@ -279,13 +279,6 @@ void ArrayConstructorDescriptor::InitializePlatformSpecific(
|
||||
}
|
||||
|
||||
|
||||
void InternalArrayConstructorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// stack param count needs (constructor pointer, and single argument)
|
||||
Register registers[] = {r1, r0};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void VarArgFunctionDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// stack param count needs (arg count)
|
||||
|
@ -22,49 +22,17 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
#define __ ACCESS_MASM(masm)
|
||||
|
||||
static void InitializeArrayConstructorDescriptor(
|
||||
Isolate* isolate, CodeStubDescriptor* descriptor,
|
||||
int constant_stack_parameter_count) {
|
||||
// cp: context
|
||||
// x1: function
|
||||
// x2: allocation site with elements kind
|
||||
// x0: number of arguments to the constructor function
|
||||
Address deopt_handler = Runtime::FunctionForId(
|
||||
Runtime::kArrayConstructor)->entry;
|
||||
|
||||
if (constant_stack_parameter_count == 0) {
|
||||
descriptor->Initialize(deopt_handler, constant_stack_parameter_count,
|
||||
JS_FUNCTION_STUB_MODE);
|
||||
} else {
|
||||
descriptor->Initialize(x0, deopt_handler, constant_stack_parameter_count,
|
||||
JS_FUNCTION_STUB_MODE);
|
||||
}
|
||||
void ArrayNArgumentsConstructorStub::Generate(MacroAssembler* masm) {
|
||||
__ Mov(x5, Operand(x0, LSL, kPointerSizeLog2));
|
||||
__ Str(x1, MemOperand(jssp, x5));
|
||||
__ Push(x1);
|
||||
__ Push(x2);
|
||||
__ Add(x0, x0, Operand(3));
|
||||
__ TailCallRuntime(Runtime::kNewArray);
|
||||
}
|
||||
|
||||
|
||||
void ArrayNArgumentsConstructorStub::InitializeDescriptor(
|
||||
CodeStubDescriptor* descriptor) {
|
||||
InitializeArrayConstructorDescriptor(isolate(), descriptor, -1);
|
||||
}
|
||||
|
||||
|
||||
static void InitializeInternalArrayConstructorDescriptor(
|
||||
Isolate* isolate, CodeStubDescriptor* descriptor,
|
||||
int constant_stack_parameter_count) {
|
||||
Address deopt_handler = Runtime::FunctionForId(
|
||||
Runtime::kInternalArrayConstructor)->entry;
|
||||
|
||||
if (constant_stack_parameter_count == 0) {
|
||||
descriptor->Initialize(deopt_handler, constant_stack_parameter_count,
|
||||
JS_FUNCTION_STUB_MODE);
|
||||
} else {
|
||||
descriptor->Initialize(x0, deopt_handler, constant_stack_parameter_count,
|
||||
JS_FUNCTION_STUB_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FastArrayPushStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
|
||||
Address deopt_handler = Runtime::FunctionForId(Runtime::kArrayPush)->entry;
|
||||
descriptor->Initialize(x0, deopt_handler, -1, JS_FUNCTION_STUB_MODE);
|
||||
@ -76,15 +44,6 @@ void FastFunctionBindStub::InitializeDescriptor(
|
||||
descriptor->Initialize(x0, deopt_handler, -1, JS_FUNCTION_STUB_MODE);
|
||||
}
|
||||
|
||||
void InternalArrayNArgumentsConstructorStub::InitializeDescriptor(
|
||||
CodeStubDescriptor* descriptor) {
|
||||
InitializeInternalArrayConstructorDescriptor(isolate(), descriptor, -1);
|
||||
}
|
||||
|
||||
|
||||
#define __ ACCESS_MASM(masm)
|
||||
|
||||
|
||||
void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm,
|
||||
ExternalReference miss) {
|
||||
// Update the static counter each time a new code stub is generated.
|
||||
@ -980,7 +939,7 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
|
||||
CEntryStub::GenerateAheadOfTime(isolate);
|
||||
StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate);
|
||||
StubFailureTrampolineStub::GenerateAheadOfTime(isolate);
|
||||
ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
|
||||
CommonArrayConstructorStub::GenerateStubsAheadOfTime(isolate);
|
||||
CreateAllocationSiteStub::GenerateAheadOfTime(isolate);
|
||||
CreateWeakCellStub::GenerateAheadOfTime(isolate);
|
||||
BinaryOpICStub::GenerateAheadOfTime(isolate);
|
||||
@ -4390,19 +4349,13 @@ static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) {
|
||||
void CommonArrayConstructorStub::GenerateStubsAheadOfTime(Isolate* isolate) {
|
||||
ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>(
|
||||
isolate);
|
||||
ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>(
|
||||
isolate);
|
||||
ArrayConstructorStubAheadOfTimeHelper<ArrayNArgumentsConstructorStub>(
|
||||
isolate);
|
||||
}
|
||||
|
||||
|
||||
void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
|
||||
Isolate* isolate) {
|
||||
ArrayNArgumentsConstructorStub stub(isolate);
|
||||
stub.GetCode();
|
||||
ElementsKind kinds[2] = { FAST_ELEMENTS, FAST_HOLEY_ELEMENTS };
|
||||
for (int i = 0; i < 2; i++) {
|
||||
// For internal arrays we only need a few things
|
||||
@ -4410,8 +4363,6 @@ void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
|
||||
stubh1.GetCode();
|
||||
InternalArraySingleArgumentConstructorStub stubh2(isolate, kinds[i]);
|
||||
stubh2.GetCode();
|
||||
InternalArrayNArgumentsConstructorStub stubh3(isolate, kinds[i]);
|
||||
stubh3.GetCode();
|
||||
}
|
||||
}
|
||||
|
||||
@ -4435,14 +4386,15 @@ void ArrayConstructorStub::GenerateDispatchToArrayStub(
|
||||
|
||||
__ Bind(&n_case);
|
||||
// N arguments.
|
||||
CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
|
||||
|
||||
ArrayNArgumentsConstructorStub stub(masm->isolate());
|
||||
__ TailCallStub(&stub);
|
||||
} else if (argument_count() == NONE) {
|
||||
CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
|
||||
} else if (argument_count() == ONE) {
|
||||
CreateArrayDispatchOneArgument(masm, mode);
|
||||
} else if (argument_count() == MORE_THAN_ONE) {
|
||||
CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
|
||||
ArrayNArgumentsConstructorStub stub(masm->isolate());
|
||||
__ TailCallStub(&stub);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -4557,7 +4509,7 @@ void InternalArrayConstructorStub::GenerateCase(
|
||||
|
||||
__ Bind(&n_case);
|
||||
// N arguments.
|
||||
InternalArrayNArgumentsConstructorStub stubN(isolate(), kind);
|
||||
ArrayNArgumentsConstructorStub stubN(isolate());
|
||||
__ TailCallStub(&stubN);
|
||||
}
|
||||
|
||||
|
@ -296,21 +296,13 @@ void ArraySingleArgumentConstructorDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
|
||||
}
|
||||
|
||||
void ArrayConstructorDescriptor::InitializePlatformSpecific(
|
||||
void ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// stack param count needs (constructor pointer, and single argument)
|
||||
Register registers[] = {x1, x2, x0};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
void InternalArrayConstructorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// stack param count needs (constructor pointer, and single argument)
|
||||
Register registers[] = {x1, x0};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void VarArgFunctionDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// stack param count needs (arg count)
|
||||
|
@ -85,18 +85,10 @@ class CodeStubGraphBuilderBase : public HGraphBuilder {
|
||||
HValue* EmitKeyedSloppyArguments(HValue* receiver, HValue* key,
|
||||
HValue* value);
|
||||
|
||||
HValue* BuildArrayConstructor(ElementsKind kind,
|
||||
AllocationSiteOverrideMode override_mode);
|
||||
HValue* BuildInternalArrayConstructor(ElementsKind kind);
|
||||
|
||||
HValue* BuildToString(HValue* input, bool convert);
|
||||
HValue* BuildToPrimitive(HValue* input, HValue* input_map);
|
||||
|
||||
private:
|
||||
HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder);
|
||||
HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder,
|
||||
ElementsKind kind);
|
||||
|
||||
base::SmartArrayPointer<HParameter*> parameters_;
|
||||
HValue* arguments_length_;
|
||||
CompilationInfo* info_;
|
||||
@ -1456,108 +1448,6 @@ Handle<Code> TransitionElementsKindStub::GenerateCode() {
|
||||
return DoGenerateCode(this);
|
||||
}
|
||||
|
||||
HValue* CodeStubGraphBuilderBase::BuildArrayConstructor(
|
||||
ElementsKind kind, AllocationSiteOverrideMode override_mode) {
|
||||
HValue* constructor = GetParameter(ArrayConstructorStubBase::kConstructor);
|
||||
HValue* alloc_site = GetParameter(ArrayConstructorStubBase::kAllocationSite);
|
||||
JSArrayBuilder array_builder(this, kind, alloc_site, constructor,
|
||||
override_mode);
|
||||
return BuildArrayNArgumentsConstructor(&array_builder, kind);
|
||||
}
|
||||
|
||||
HValue* CodeStubGraphBuilderBase::BuildInternalArrayConstructor(
|
||||
ElementsKind kind) {
|
||||
HValue* constructor = GetParameter(
|
||||
InternalArrayConstructorStubBase::kConstructor);
|
||||
JSArrayBuilder array_builder(this, kind, constructor);
|
||||
return BuildArrayNArgumentsConstructor(&array_builder, kind);
|
||||
}
|
||||
|
||||
|
||||
HValue* CodeStubGraphBuilderBase::BuildArraySingleArgumentConstructor(
|
||||
JSArrayBuilder* array_builder) {
|
||||
// Smi check and range check on the input arg.
|
||||
HValue* constant_one = graph()->GetConstant1();
|
||||
HValue* constant_zero = graph()->GetConstant0();
|
||||
|
||||
HInstruction* elements = Add<HArgumentsElements>(false);
|
||||
HInstruction* argument = Add<HAccessArgumentsAt>(
|
||||
elements, constant_one, constant_zero);
|
||||
|
||||
return BuildAllocateArrayFromLength(array_builder, argument);
|
||||
}
|
||||
|
||||
|
||||
HValue* CodeStubGraphBuilderBase::BuildArrayNArgumentsConstructor(
|
||||
JSArrayBuilder* array_builder, ElementsKind kind) {
|
||||
// Insert a bounds check because the number of arguments might exceed
|
||||
// the kInitialMaxFastElementArray limit. This cannot happen for code
|
||||
// that was parsed, but calling via Array.apply(thisArg, [...]) might
|
||||
// trigger it.
|
||||
HValue* length = GetArgumentsLength();
|
||||
HConstant* max_alloc_length =
|
||||
Add<HConstant>(JSArray::kInitialMaxFastElementArray);
|
||||
HValue* checked_length = Add<HBoundsCheck>(length, max_alloc_length);
|
||||
|
||||
// We need to fill with the hole if it's a smi array in the multi-argument
|
||||
// case because we might have to bail out while copying arguments into
|
||||
// the array because they aren't compatible with a smi array.
|
||||
// If it's a double array, no problem, and if it's fast then no
|
||||
// problem either because doubles are boxed.
|
||||
//
|
||||
// TODO(mvstanton): consider an instruction to memset fill the array
|
||||
// with zero in this case instead.
|
||||
JSArrayBuilder::FillMode fill_mode = IsFastSmiElementsKind(kind)
|
||||
? JSArrayBuilder::FILL_WITH_HOLE
|
||||
: JSArrayBuilder::DONT_FILL_WITH_HOLE;
|
||||
HValue* new_object = array_builder->AllocateArray(checked_length,
|
||||
checked_length,
|
||||
fill_mode);
|
||||
HValue* elements = array_builder->GetElementsLocation();
|
||||
DCHECK(elements != NULL);
|
||||
|
||||
// Now populate the elements correctly.
|
||||
LoopBuilder builder(this,
|
||||
context(),
|
||||
LoopBuilder::kPostIncrement);
|
||||
HValue* start = graph()->GetConstant0();
|
||||
HValue* key = builder.BeginBody(start, checked_length, Token::LT);
|
||||
HInstruction* argument_elements = Add<HArgumentsElements>(false);
|
||||
HInstruction* argument = Add<HAccessArgumentsAt>(
|
||||
argument_elements, checked_length, key);
|
||||
|
||||
Add<HStoreKeyed>(elements, key, argument, nullptr, kind);
|
||||
builder.EndBody();
|
||||
return new_object;
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
HValue* CodeStubGraphBuilder<ArrayNArgumentsConstructorStub>::BuildCodeStub() {
|
||||
ElementsKind kind = casted_stub()->elements_kind();
|
||||
AllocationSiteOverrideMode override_mode = casted_stub()->override_mode();
|
||||
return BuildArrayConstructor(kind, override_mode);
|
||||
}
|
||||
|
||||
|
||||
Handle<Code> ArrayNArgumentsConstructorStub::GenerateCode() {
|
||||
return DoGenerateCode(this);
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
HValue* CodeStubGraphBuilder<InternalArrayNArgumentsConstructorStub>::
|
||||
BuildCodeStub() {
|
||||
ElementsKind kind = casted_stub()->elements_kind();
|
||||
return BuildInternalArrayConstructor(kind);
|
||||
}
|
||||
|
||||
|
||||
Handle<Code> InternalArrayNArgumentsConstructorStub::GenerateCode() {
|
||||
return DoGenerateCode(this);
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
HValue* CodeStubGraphBuilder<BinaryOpICStub>::BuildCodeInitializedStub() {
|
||||
BinaryOpICState state = casted_stub()->state();
|
||||
|
@ -4466,16 +4466,6 @@ void ArrayConstructorStub::PrintName(std::ostream& os) const { // NOLINT
|
||||
}
|
||||
|
||||
|
||||
std::ostream& ArrayConstructorStubBase::BasePrintName(
|
||||
std::ostream& os, // NOLINT
|
||||
const char* name) const {
|
||||
os << name << "_" << ElementsKindToString(elements_kind());
|
||||
if (override_mode() == DISABLE_ALLOCATION_SITES) {
|
||||
os << "_DISABLE_ALLOCATION_SITES";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
bool ToBooleanICStub::UpdateStatus(Handle<Object> object) {
|
||||
Types new_types = types();
|
||||
Types old_types = new_types;
|
||||
@ -4613,7 +4603,6 @@ void SingleArgumentConstructorCommon(CodeStubAssembler* assembler,
|
||||
ElementsKind elements_kind,
|
||||
compiler::Node* array_map,
|
||||
compiler::Node* allocation_site,
|
||||
Runtime::FunctionId runtime_fallback,
|
||||
AllocationSiteMode mode) {
|
||||
typedef compiler::Node Node;
|
||||
typedef CodeStubAssembler::Label Label;
|
||||
@ -4652,21 +4641,14 @@ void SingleArgumentConstructorCommon(CodeStubAssembler* assembler,
|
||||
{
|
||||
Node* context = assembler->Parameter(
|
||||
ArraySingleArgumentConstructorDescriptor::kContextIndex);
|
||||
Node* constructor = assembler->Parameter(
|
||||
Node* function = assembler->Parameter(
|
||||
ArraySingleArgumentConstructorDescriptor::kFunctionIndex);
|
||||
Node* argument_count = assembler->Parameter(
|
||||
ArraySingleArgumentConstructorDescriptor::kArgumentsCountIndex);
|
||||
Node* argument_base_offset = assembler->IntPtrAdd(
|
||||
assembler->IntPtrConstant(CommonFrameConstants::kFixedFrameSizeAboveFp -
|
||||
kPointerSize),
|
||||
assembler->Word32Shl(argument_count,
|
||||
assembler->IntPtrConstant(kPointerSizeLog2)));
|
||||
Node* argument_base = assembler->IntPtrAdd(assembler->LoadFramePointer(),
|
||||
argument_base_offset);
|
||||
Node* array = assembler->CallRuntime(
|
||||
runtime_fallback, context, constructor, argument_base,
|
||||
assembler->SmiTag(argument_count), allocation_site);
|
||||
assembler->Return(array);
|
||||
Node* array_size = assembler->Parameter(
|
||||
ArraySingleArgumentConstructorDescriptor::kArraySizeSmiParameterIndex);
|
||||
Node* allocation_site = assembler->Parameter(
|
||||
ArraySingleArgumentConstructorDescriptor::kAllocationSiteIndex);
|
||||
assembler->TailCallRuntime(Runtime::kNewArray, context, function,
|
||||
array_size, function, allocation_site);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
@ -4685,9 +4667,8 @@ void ArraySingleArgumentConstructorStub::GenerateAssembly(
|
||||
: AllocationSite::GetMode(elements_kind());
|
||||
Node* allocation_site = assembler->Parameter(
|
||||
ArrayNoArgumentConstructorDescriptor::kAllocationSiteIndex);
|
||||
SingleArgumentConstructorCommon(
|
||||
assembler, elements_kind(), array_map, allocation_site,
|
||||
Runtime::kArraySingleArgumentConstructor, mode);
|
||||
SingleArgumentConstructorCommon(assembler, elements_kind(), array_map,
|
||||
allocation_site, mode);
|
||||
}
|
||||
|
||||
void InternalArraySingleArgumentConstructorStub::GenerateAssembly(
|
||||
@ -4697,15 +4678,14 @@ void InternalArraySingleArgumentConstructorStub::GenerateAssembly(
|
||||
ArraySingleArgumentConstructorDescriptor::kFunctionIndex);
|
||||
Node* array_map = assembler->LoadObjectField(
|
||||
function, JSFunction::kPrototypeOrInitialMapOffset);
|
||||
SingleArgumentConstructorCommon(
|
||||
assembler, elements_kind(), array_map, assembler->UndefinedConstant(),
|
||||
Runtime::kArraySingleArgumentConstructor, DONT_TRACK_ALLOCATION_SITE);
|
||||
SingleArgumentConstructorCommon(assembler, elements_kind(), array_map,
|
||||
assembler->UndefinedConstant(),
|
||||
DONT_TRACK_ALLOCATION_SITE);
|
||||
}
|
||||
|
||||
ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate)
|
||||
: PlatformCodeStub(isolate) {
|
||||
minor_key_ = ArgumentCountBits::encode(ANY);
|
||||
ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
|
||||
}
|
||||
|
||||
|
||||
@ -4721,15 +4701,10 @@ ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate,
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
|
||||
}
|
||||
|
||||
|
||||
InternalArrayConstructorStub::InternalArrayConstructorStub(
|
||||
Isolate* isolate) : PlatformCodeStub(isolate) {
|
||||
InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
|
||||
}
|
||||
|
||||
InternalArrayConstructorStub::InternalArrayConstructorStub(Isolate* isolate)
|
||||
: PlatformCodeStub(isolate) {}
|
||||
|
||||
Representation RepresentationFromType(Type* type) {
|
||||
if (type->Is(Type::UntaggedIntegral())) {
|
||||
|
109
src/code-stubs.h
109
src/code-stubs.h
@ -53,7 +53,6 @@ namespace internal {
|
||||
V(VectorStoreIC) \
|
||||
V(VectorKeyedStoreIC) \
|
||||
/* HydrogenCodeStubs */ \
|
||||
V(ArrayNArgumentsConstructor) \
|
||||
V(BinaryOpIC) \
|
||||
V(BinaryOpWithAllocationSite) \
|
||||
V(CreateAllocationSite) \
|
||||
@ -70,7 +69,6 @@ namespace internal {
|
||||
V(FastNewSloppyArguments) \
|
||||
V(FastNewStrictArguments) \
|
||||
V(GrowArrayElements) \
|
||||
V(InternalArrayNArgumentsConstructor) \
|
||||
V(KeyedLoadGeneric) \
|
||||
V(LoadGlobalViaContext) \
|
||||
V(LoadScriptContextField) \
|
||||
@ -101,6 +99,7 @@ namespace internal {
|
||||
V(AllocateBool8x16) \
|
||||
V(ArrayNoArgumentConstructor) \
|
||||
V(ArraySingleArgumentConstructor) \
|
||||
V(ArrayNArgumentsConstructor) \
|
||||
V(StringLength) \
|
||||
V(Add) \
|
||||
V(Subtract) \
|
||||
@ -1301,7 +1300,7 @@ class ArrayConstructorStub: public PlatformCodeStub {
|
||||
|
||||
class ArgumentCountBits : public BitField<ArgumentCountKey, 0, 2> {};
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayConstructor);
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayNArgumentsConstructor);
|
||||
DEFINE_PLATFORM_CODE_STUB(ArrayConstructor, PlatformCodeStub);
|
||||
};
|
||||
|
||||
@ -1313,7 +1312,7 @@ class InternalArrayConstructorStub: public PlatformCodeStub {
|
||||
private:
|
||||
void GenerateCase(MacroAssembler* masm, ElementsKind kind);
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(InternalArrayConstructor);
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayNArgumentsConstructor);
|
||||
DEFINE_PLATFORM_CODE_STUB(InternalArrayConstructor, PlatformCodeStub);
|
||||
};
|
||||
|
||||
@ -2788,50 +2787,6 @@ class AllocateHeapNumberStub : public TurboFanCodeStub {
|
||||
SIMD128_TYPES(SIMD128_ALLOC_STUB)
|
||||
#undef SIMD128_ALLOC_STUB
|
||||
|
||||
class ArrayConstructorStubBase : public HydrogenCodeStub {
|
||||
public:
|
||||
ArrayConstructorStubBase(Isolate* isolate,
|
||||
ElementsKind kind,
|
||||
AllocationSiteOverrideMode override_mode)
|
||||
: HydrogenCodeStub(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));
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// Parameters accessed via CodeStubGraphBuilder::GetParameter()
|
||||
static const int kConstructor = 0;
|
||||
static const int kAllocationSite = 1;
|
||||
|
||||
protected:
|
||||
std::ostream& BasePrintName(std::ostream& os,
|
||||
const char* name) const; // NOLINT
|
||||
|
||||
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
|
||||
|
||||
DEFINE_CODE_STUB_BASE(ArrayConstructorStubBase, HydrogenCodeStub);
|
||||
};
|
||||
|
||||
class CommonArrayConstructorStub : public TurboFanCodeStub {
|
||||
protected:
|
||||
CommonArrayConstructorStub(Isolate* isolate, ElementsKind kind,
|
||||
@ -2862,6 +2817,8 @@ class CommonArrayConstructorStub : public TurboFanCodeStub {
|
||||
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);
|
||||
@ -2938,61 +2895,19 @@ class InternalArraySingleArgumentConstructorStub
|
||||
CommonArrayConstructorStub);
|
||||
};
|
||||
|
||||
class ArrayNArgumentsConstructorStub : public ArrayConstructorStubBase {
|
||||
class ArrayNArgumentsConstructorStub : public PlatformCodeStub {
|
||||
public:
|
||||
ArrayNArgumentsConstructorStub(
|
||||
Isolate* isolate,
|
||||
ElementsKind kind,
|
||||
AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
|
||||
: ArrayConstructorStubBase(isolate, kind, override_mode) {
|
||||
explicit ArrayNArgumentsConstructorStub(Isolate* isolate)
|
||||
: PlatformCodeStub(isolate) {}
|
||||
|
||||
CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
|
||||
return ArrayNArgumentsConstructorDescriptor(isolate());
|
||||
}
|
||||
|
||||
private:
|
||||
void PrintName(std::ostream& os) const override { // NOLINT
|
||||
BasePrintName(os, "ArrayNArgumentsConstructorStub");
|
||||
}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayConstructor);
|
||||
DEFINE_HYDROGEN_CODE_STUB(ArrayNArgumentsConstructor,
|
||||
ArrayConstructorStubBase);
|
||||
DEFINE_PLATFORM_CODE_STUB(ArrayNArgumentsConstructor, PlatformCodeStub);
|
||||
};
|
||||
|
||||
|
||||
class InternalArrayConstructorStubBase : public HydrogenCodeStub {
|
||||
public:
|
||||
InternalArrayConstructorStubBase(Isolate* isolate, ElementsKind kind)
|
||||
: HydrogenCodeStub(isolate) {
|
||||
set_sub_minor_key(ElementsKindBits::encode(kind));
|
||||
}
|
||||
|
||||
static void GenerateStubsAheadOfTime(Isolate* isolate);
|
||||
|
||||
// Parameters accessed via CodeStubGraphBuilder::GetParameter()
|
||||
static const int kConstructor = 0;
|
||||
|
||||
ElementsKind elements_kind() const {
|
||||
return ElementsKindBits::decode(sub_minor_key());
|
||||
}
|
||||
|
||||
private:
|
||||
class ElementsKindBits : public BitField<ElementsKind, 0, 8> {};
|
||||
|
||||
DEFINE_CODE_STUB_BASE(InternalArrayConstructorStubBase, HydrogenCodeStub);
|
||||
};
|
||||
|
||||
|
||||
class InternalArrayNArgumentsConstructorStub : public
|
||||
InternalArrayConstructorStubBase {
|
||||
public:
|
||||
InternalArrayNArgumentsConstructorStub(Isolate* isolate, ElementsKind kind)
|
||||
: InternalArrayConstructorStubBase(isolate, kind) { }
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(InternalArrayConstructor);
|
||||
DEFINE_HYDROGEN_CODE_STUB(InternalArrayNArgumentsConstructor,
|
||||
InternalArrayConstructorStubBase);
|
||||
};
|
||||
|
||||
|
||||
class StoreElementStub : public PlatformCodeStub {
|
||||
public:
|
||||
StoreElementStub(Isolate* isolate, ElementsKind elements_kind,
|
||||
|
@ -450,8 +450,7 @@ void JSGenericLowering::LowerJSCreateArray(Node* node) {
|
||||
node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant());
|
||||
NodeProperties::ChangeOp(node, common()->Call(desc));
|
||||
} else {
|
||||
ArrayNArgumentsConstructorStub stub(isolate(), elements_kind,
|
||||
override_mode);
|
||||
ArrayNArgumentsConstructorStub stub(isolate());
|
||||
CallDescriptor* desc = Linkage::GetStubCallDescriptor(
|
||||
isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(),
|
||||
arity + 1, CallDescriptor::kNeedsFrameState);
|
||||
|
@ -3707,14 +3707,8 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
|
||||
DCHECK(ToRegister(instr->result()).is(r0));
|
||||
|
||||
__ mov(r0, Operand(instr->arity()));
|
||||
if (instr->arity() == 1) {
|
||||
// We only need the allocation site for the case we have a length argument.
|
||||
// The case may bail out to the runtime, which will determine the correct
|
||||
// elements kind with the site.
|
||||
__ Move(r2, instr->hydrogen()->site());
|
||||
} else {
|
||||
__ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
|
||||
}
|
||||
__ Move(r2, instr->hydrogen()->site());
|
||||
|
||||
ElementsKind kind = instr->hydrogen()->elements_kind();
|
||||
AllocationSiteOverrideMode override_mode =
|
||||
(AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE)
|
||||
@ -3747,7 +3741,7 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
|
||||
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
||||
__ bind(&done);
|
||||
} else {
|
||||
ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode);
|
||||
ArrayNArgumentsConstructorStub stub(isolate());
|
||||
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
||||
}
|
||||
}
|
||||
|
@ -364,15 +364,7 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
|
||||
DCHECK(ToRegister(instr->constructor()).is(x1));
|
||||
|
||||
__ Mov(x0, Operand(instr->arity()));
|
||||
if (instr->arity() == 1) {
|
||||
// We only need the allocation site for the case we have a length argument.
|
||||
// The case may bail out to the runtime, which will determine the correct
|
||||
// elements kind with the site.
|
||||
__ Mov(x2, instr->hydrogen()->site());
|
||||
} else {
|
||||
__ LoadRoot(x2, Heap::kUndefinedValueRootIndex);
|
||||
}
|
||||
|
||||
__ Mov(x2, instr->hydrogen()->site());
|
||||
|
||||
ElementsKind kind = instr->hydrogen()->elements_kind();
|
||||
AllocationSiteOverrideMode override_mode =
|
||||
@ -405,7 +397,7 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
|
||||
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
||||
__ Bind(&done);
|
||||
} else {
|
||||
ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode);
|
||||
ArrayNArgumentsConstructorStub stub(isolate());
|
||||
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
||||
}
|
||||
RecordPushedArgumentsDelta(instr->hydrogen()->argument_delta());
|
||||
|
@ -3515,14 +3515,7 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
|
||||
DCHECK(ToRegister(instr->result()).is(eax));
|
||||
|
||||
__ Move(eax, Immediate(instr->arity()));
|
||||
if (instr->arity() == 1) {
|
||||
// We only need the allocation site for the case we have a length argument.
|
||||
// The case may bail out to the runtime, which will determine the correct
|
||||
// elements kind with the site.
|
||||
__ mov(ebx, instr->hydrogen()->site());
|
||||
} else {
|
||||
__ mov(ebx, isolate()->factory()->undefined_value());
|
||||
}
|
||||
__ mov(ebx, instr->hydrogen()->site());
|
||||
|
||||
ElementsKind kind = instr->hydrogen()->elements_kind();
|
||||
AllocationSiteOverrideMode override_mode =
|
||||
@ -3556,7 +3549,7 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
|
||||
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
||||
__ bind(&done);
|
||||
} else {
|
||||
ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode);
|
||||
ArrayNArgumentsConstructorStub stub(isolate());
|
||||
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
||||
}
|
||||
}
|
||||
|
@ -3639,14 +3639,8 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
|
||||
DCHECK(ToRegister(instr->result()).is(v0));
|
||||
|
||||
__ li(a0, Operand(instr->arity()));
|
||||
if (instr->arity() == 1) {
|
||||
// We only need the allocation site for the case we have a length argument.
|
||||
// The case may bail out to the runtime, which will determine the correct
|
||||
// elements kind with the site.
|
||||
__ li(a2, instr->hydrogen()->site());
|
||||
} else {
|
||||
__ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
|
||||
}
|
||||
__ li(a2, instr->hydrogen()->site());
|
||||
|
||||
ElementsKind kind = instr->hydrogen()->elements_kind();
|
||||
AllocationSiteOverrideMode override_mode =
|
||||
(AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE)
|
||||
@ -3678,7 +3672,7 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
|
||||
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
||||
__ bind(&done);
|
||||
} else {
|
||||
ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode);
|
||||
ArrayNArgumentsConstructorStub stub(isolate());
|
||||
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
||||
}
|
||||
}
|
||||
|
@ -1166,7 +1166,7 @@ void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
|
||||
DCHECK(!result.is(dividend) || !scratch.is(dividend));
|
||||
|
||||
// If the divisor is 1, return the dividend.
|
||||
if (divisor == 1) {
|
||||
if (divisor == 0) {
|
||||
__ Move(result, dividend);
|
||||
return;
|
||||
}
|
||||
@ -3839,14 +3839,8 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
|
||||
DCHECK(ToRegister(instr->result()).is(v0));
|
||||
|
||||
__ li(a0, Operand(instr->arity()));
|
||||
if (instr->arity() == 1) {
|
||||
// We only need the allocation site for the case we have a length argument.
|
||||
// The case may bail out to the runtime, which will determine the correct
|
||||
// elements kind with the site.
|
||||
__ li(a2, instr->hydrogen()->site());
|
||||
} else {
|
||||
__ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
|
||||
}
|
||||
__ li(a2, instr->hydrogen()->site());
|
||||
|
||||
ElementsKind kind = instr->hydrogen()->elements_kind();
|
||||
AllocationSiteOverrideMode override_mode =
|
||||
(AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE)
|
||||
@ -3878,7 +3872,7 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
|
||||
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
||||
__ bind(&done);
|
||||
} else {
|
||||
ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode);
|
||||
ArrayNArgumentsConstructorStub stub(isolate());
|
||||
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
||||
}
|
||||
}
|
||||
|
@ -3707,14 +3707,7 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
|
||||
DCHECK(ToRegister(instr->result()).is(rax));
|
||||
|
||||
__ Set(rax, instr->arity());
|
||||
if (instr->arity() == 1) {
|
||||
// We only need the allocation site for the case we have a length argument.
|
||||
// The case may bail out to the runtime, which will determine the correct
|
||||
// elements kind with the site.
|
||||
__ Move(rbx, instr->hydrogen()->site());
|
||||
} else {
|
||||
__ LoadRoot(rbx, Heap::kUndefinedValueRootIndex);
|
||||
}
|
||||
__ Move(rbx, instr->hydrogen()->site());
|
||||
|
||||
ElementsKind kind = instr->hydrogen()->elements_kind();
|
||||
AllocationSiteOverrideMode override_mode =
|
||||
@ -3748,7 +3741,7 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
|
||||
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
||||
__ bind(&done);
|
||||
} else {
|
||||
ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode);
|
||||
ArrayNArgumentsConstructorStub stub(isolate());
|
||||
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
||||
}
|
||||
}
|
||||
|
@ -22,52 +22,18 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
#define __ ACCESS_MASM(masm)
|
||||
|
||||
static void InitializeArrayConstructorDescriptor(
|
||||
Isolate* isolate, CodeStubDescriptor* descriptor,
|
||||
int constant_stack_parameter_count) {
|
||||
// register state
|
||||
// eax -- number of arguments
|
||||
// edi -- function
|
||||
// ebx -- allocation site with elements kind
|
||||
Address deopt_handler = Runtime::FunctionForId(
|
||||
Runtime::kArrayConstructor)->entry;
|
||||
|
||||
if (constant_stack_parameter_count == 0) {
|
||||
descriptor->Initialize(deopt_handler, constant_stack_parameter_count,
|
||||
JS_FUNCTION_STUB_MODE);
|
||||
} else {
|
||||
descriptor->Initialize(eax, deopt_handler, constant_stack_parameter_count,
|
||||
JS_FUNCTION_STUB_MODE);
|
||||
}
|
||||
void ArrayNArgumentsConstructorStub::Generate(MacroAssembler* masm) {
|
||||
__ pop(ecx);
|
||||
__ mov(MemOperand(esp, eax, times_4, 0), edi);
|
||||
__ push(edi);
|
||||
__ push(ebx);
|
||||
__ push(ecx);
|
||||
__ add(eax, Immediate(3));
|
||||
__ TailCallRuntime(Runtime::kNewArray);
|
||||
}
|
||||
|
||||
|
||||
static void InitializeInternalArrayConstructorDescriptor(
|
||||
Isolate* isolate, CodeStubDescriptor* descriptor,
|
||||
int constant_stack_parameter_count) {
|
||||
// register state
|
||||
// eax -- number of arguments
|
||||
// edi -- constructor function
|
||||
Address deopt_handler = Runtime::FunctionForId(
|
||||
Runtime::kInternalArrayConstructor)->entry;
|
||||
|
||||
if (constant_stack_parameter_count == 0) {
|
||||
descriptor->Initialize(deopt_handler, constant_stack_parameter_count,
|
||||
JS_FUNCTION_STUB_MODE);
|
||||
} else {
|
||||
descriptor->Initialize(eax, deopt_handler, constant_stack_parameter_count,
|
||||
JS_FUNCTION_STUB_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ArrayNArgumentsConstructorStub::InitializeDescriptor(
|
||||
CodeStubDescriptor* descriptor) {
|
||||
InitializeArrayConstructorDescriptor(isolate(), descriptor, -1);
|
||||
}
|
||||
|
||||
|
||||
void FastArrayPushStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
|
||||
Address deopt_handler = Runtime::FunctionForId(Runtime::kArrayPush)->entry;
|
||||
descriptor->Initialize(eax, deopt_handler, -1, JS_FUNCTION_STUB_MODE);
|
||||
@ -79,15 +45,6 @@ void FastFunctionBindStub::InitializeDescriptor(
|
||||
descriptor->Initialize(eax, deopt_handler, -1, JS_FUNCTION_STUB_MODE);
|
||||
}
|
||||
|
||||
void InternalArrayNArgumentsConstructorStub::InitializeDescriptor(
|
||||
CodeStubDescriptor* descriptor) {
|
||||
InitializeInternalArrayConstructorDescriptor(isolate(), descriptor, -1);
|
||||
}
|
||||
|
||||
|
||||
#define __ ACCESS_MASM(masm)
|
||||
|
||||
|
||||
void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm,
|
||||
ExternalReference miss) {
|
||||
// Update the static counter each time a new code stub is generated.
|
||||
@ -1782,7 +1739,7 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
|
||||
StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate);
|
||||
StubFailureTrampolineStub::GenerateAheadOfTime(isolate);
|
||||
// It is important that the store buffer overflow stubs are generated first.
|
||||
ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
|
||||
CommonArrayConstructorStub::GenerateStubsAheadOfTime(isolate);
|
||||
CreateAllocationSiteStub::GenerateAheadOfTime(isolate);
|
||||
CreateWeakCellStub::GenerateAheadOfTime(isolate);
|
||||
BinaryOpICStub::GenerateAheadOfTime(isolate);
|
||||
@ -4269,19 +4226,14 @@ static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) {
|
||||
void CommonArrayConstructorStub::GenerateStubsAheadOfTime(Isolate* isolate) {
|
||||
ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>(
|
||||
isolate);
|
||||
ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>(
|
||||
isolate);
|
||||
ArrayConstructorStubAheadOfTimeHelper<ArrayNArgumentsConstructorStub>(
|
||||
isolate);
|
||||
}
|
||||
ArrayNArgumentsConstructorStub stub(isolate);
|
||||
stub.GetCode();
|
||||
|
||||
|
||||
void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
|
||||
Isolate* isolate) {
|
||||
ElementsKind kinds[2] = { FAST_ELEMENTS, FAST_HOLEY_ELEMENTS };
|
||||
for (int i = 0; i < 2; i++) {
|
||||
// For internal arrays we only need a few things
|
||||
@ -4289,8 +4241,6 @@ void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
|
||||
stubh1.GetCode();
|
||||
InternalArraySingleArgumentConstructorStub stubh2(isolate, kinds[i]);
|
||||
stubh2.GetCode();
|
||||
InternalArrayNArgumentsConstructorStub stubh3(isolate, kinds[i]);
|
||||
stubh3.GetCode();
|
||||
}
|
||||
}
|
||||
|
||||
@ -4310,13 +4260,15 @@ void ArrayConstructorStub::GenerateDispatchToArrayStub(
|
||||
CreateArrayDispatchOneArgument(masm, mode);
|
||||
|
||||
__ bind(¬_one_case);
|
||||
CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
|
||||
ArrayNArgumentsConstructorStub stub(masm->isolate());
|
||||
__ TailCallStub(&stub);
|
||||
} else if (argument_count() == NONE) {
|
||||
CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
|
||||
} else if (argument_count() == ONE) {
|
||||
CreateArrayDispatchOneArgument(masm, mode);
|
||||
} else if (argument_count() == MORE_THAN_ONE) {
|
||||
CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
|
||||
ArrayNArgumentsConstructorStub stub(masm->isolate());
|
||||
__ TailCallStub(&stub);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -4428,7 +4380,7 @@ void InternalArrayConstructorStub::GenerateCase(
|
||||
__ TailCallStub(&stub1);
|
||||
|
||||
__ bind(¬_one_case);
|
||||
InternalArrayNArgumentsConstructorStub stubN(isolate(), kind);
|
||||
ArrayNArgumentsConstructorStub stubN(isolate());
|
||||
__ TailCallStub(&stubN);
|
||||
}
|
||||
|
||||
|
@ -275,19 +275,14 @@ void ArraySingleArgumentConstructorDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
|
||||
}
|
||||
|
||||
void ArrayConstructorDescriptor::InitializePlatformSpecific(
|
||||
void ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// stack param count needs (constructor pointer, and single argument)
|
||||
// register state
|
||||
// eax -- number of arguments
|
||||
// edi -- function
|
||||
// ebx -- allocation site with elements kind
|
||||
Register registers[] = {edi, ebx, eax};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
void InternalArrayConstructorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// stack param count needs (constructor pointer, and single argument)
|
||||
Register registers[] = {edi, eax};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
|
||||
}
|
||||
|
||||
void VarArgFunctionDescriptor::InitializePlatformSpecific(
|
||||
|
@ -453,25 +453,14 @@ FunctionType* ArraySingleArgumentConstructorDescriptor::
|
||||
}
|
||||
|
||||
FunctionType*
|
||||
ArrayConstructorDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
ArrayNArgumentsConstructorDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 3, zone)->AsFunction();
|
||||
function->InitParameter(0, Type::Receiver()); // JSFunction
|
||||
function->InitParameter(1, AnyTagged(zone));
|
||||
function->InitParameter(2, UntaggedIntegral32(zone));
|
||||
return function;
|
||||
}
|
||||
|
||||
FunctionType*
|
||||
InternalArrayConstructorDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 2, zone)->AsFunction();
|
||||
function->InitParameter(0, Type::Receiver()); // JSFunction
|
||||
function->InitParameter(1, UntaggedIntegral32(zone));
|
||||
function->InitParameter(1, AnyTagged(zone)); // Allocation site or undefined
|
||||
function->InitParameter(2, UntaggedIntegral32(zone)); // Arg count
|
||||
return function;
|
||||
}
|
||||
|
||||
|
@ -58,8 +58,7 @@ class PlatformInterfaceDescriptor;
|
||||
V(AllocateBool8x16) \
|
||||
V(ArrayNoArgumentConstructor) \
|
||||
V(ArraySingleArgumentConstructor) \
|
||||
V(ArrayConstructor) \
|
||||
V(InternalArrayConstructor) \
|
||||
V(ArrayNArgumentsConstructor) \
|
||||
V(Compare) \
|
||||
V(BinaryOp) \
|
||||
V(BinaryOpWithAllocationSite) \
|
||||
@ -604,24 +603,23 @@ class ArraySingleArgumentConstructorDescriptor
|
||||
enum ParameterIndices {
|
||||
kFunctionIndex,
|
||||
kAllocationSiteIndex,
|
||||
kArgumentsCountIndex,
|
||||
kArgumentCountIndex,
|
||||
kFunctionParameterIndex,
|
||||
kArraySizeSmiParameterIndex,
|
||||
kContextIndex
|
||||
};
|
||||
};
|
||||
|
||||
class ArrayConstructorDescriptor : public CallInterfaceDescriptor {
|
||||
public:
|
||||
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(ArrayConstructorDescriptor,
|
||||
CallInterfaceDescriptor)
|
||||
};
|
||||
|
||||
|
||||
class InternalArrayConstructorDescriptor : public CallInterfaceDescriptor {
|
||||
class ArrayNArgumentsConstructorDescriptor : public CallInterfaceDescriptor {
|
||||
public:
|
||||
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(
|
||||
InternalArrayConstructorDescriptor, CallInterfaceDescriptor)
|
||||
ArrayNArgumentsConstructorDescriptor, CallInterfaceDescriptor)
|
||||
enum ParameterIndices {
|
||||
kFunctionIndex,
|
||||
kAllocationSiteIndex,
|
||||
kArgumentCountIndex,
|
||||
kContextIndex
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
@ -21,45 +21,18 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
#define __ ACCESS_MASM(masm)
|
||||
|
||||
static void InitializeArrayConstructorDescriptor(
|
||||
Isolate* isolate, CodeStubDescriptor* descriptor,
|
||||
int constant_stack_parameter_count) {
|
||||
Address deopt_handler = Runtime::FunctionForId(
|
||||
Runtime::kArrayConstructor)->entry;
|
||||
|
||||
if (constant_stack_parameter_count == 0) {
|
||||
descriptor->Initialize(deopt_handler, constant_stack_parameter_count,
|
||||
JS_FUNCTION_STUB_MODE);
|
||||
} else {
|
||||
descriptor->Initialize(a0, deopt_handler, constant_stack_parameter_count,
|
||||
JS_FUNCTION_STUB_MODE);
|
||||
}
|
||||
void ArrayNArgumentsConstructorStub::Generate(MacroAssembler* masm) {
|
||||
__ sll(t9, a0, kPointerSizeLog2);
|
||||
__ Addu(t9, sp, t9);
|
||||
__ sw(a1, MemOperand(t9, 0));
|
||||
__ Push(a1);
|
||||
__ Push(a2);
|
||||
__ Addu(a0, a0, Operand(3));
|
||||
__ TailCallRuntime(Runtime::kNewArray);
|
||||
}
|
||||
|
||||
|
||||
static void InitializeInternalArrayConstructorDescriptor(
|
||||
Isolate* isolate, CodeStubDescriptor* descriptor,
|
||||
int constant_stack_parameter_count) {
|
||||
Address deopt_handler = Runtime::FunctionForId(
|
||||
Runtime::kInternalArrayConstructor)->entry;
|
||||
|
||||
if (constant_stack_parameter_count == 0) {
|
||||
descriptor->Initialize(deopt_handler, constant_stack_parameter_count,
|
||||
JS_FUNCTION_STUB_MODE);
|
||||
} else {
|
||||
descriptor->Initialize(a0, deopt_handler, constant_stack_parameter_count,
|
||||
JS_FUNCTION_STUB_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ArrayNArgumentsConstructorStub::InitializeDescriptor(
|
||||
CodeStubDescriptor* descriptor) {
|
||||
InitializeArrayConstructorDescriptor(isolate(), descriptor, -1);
|
||||
}
|
||||
|
||||
|
||||
void FastArrayPushStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
|
||||
Address deopt_handler = Runtime::FunctionForId(Runtime::kArrayPush)->entry;
|
||||
descriptor->Initialize(a0, deopt_handler, -1, JS_FUNCTION_STUB_MODE);
|
||||
@ -71,14 +44,6 @@ void FastFunctionBindStub::InitializeDescriptor(
|
||||
descriptor->Initialize(a0, deopt_handler, -1, JS_FUNCTION_STUB_MODE);
|
||||
}
|
||||
|
||||
void InternalArrayNArgumentsConstructorStub::InitializeDescriptor(
|
||||
CodeStubDescriptor* descriptor) {
|
||||
InitializeInternalArrayConstructorDescriptor(isolate(), descriptor, -1);
|
||||
}
|
||||
|
||||
|
||||
#define __ ACCESS_MASM(masm)
|
||||
|
||||
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
||||
Condition cc);
|
||||
static void EmitSmiNonsmiComparison(MacroAssembler* masm,
|
||||
@ -1015,7 +980,7 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
|
||||
CEntryStub::GenerateAheadOfTime(isolate);
|
||||
StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate);
|
||||
StubFailureTrampolineStub::GenerateAheadOfTime(isolate);
|
||||
ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
|
||||
CommonArrayConstructorStub::GenerateStubsAheadOfTime(isolate);
|
||||
CreateAllocationSiteStub::GenerateAheadOfTime(isolate);
|
||||
CreateWeakCellStub::GenerateAheadOfTime(isolate);
|
||||
BinaryOpICStub::GenerateAheadOfTime(isolate);
|
||||
@ -4327,19 +4292,13 @@ static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) {
|
||||
void CommonArrayConstructorStub::GenerateStubsAheadOfTime(Isolate* isolate) {
|
||||
ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>(
|
||||
isolate);
|
||||
ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>(
|
||||
isolate);
|
||||
ArrayConstructorStubAheadOfTimeHelper<ArrayNArgumentsConstructorStub>(
|
||||
isolate);
|
||||
}
|
||||
|
||||
|
||||
void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
|
||||
Isolate* isolate) {
|
||||
ArrayNArgumentsConstructorStub stub(isolate);
|
||||
stub.GetCode();
|
||||
ElementsKind kinds[2] = { FAST_ELEMENTS, FAST_HOLEY_ELEMENTS };
|
||||
for (int i = 0; i < 2; i++) {
|
||||
// For internal arrays we only need a few things.
|
||||
@ -4347,8 +4306,6 @@ void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
|
||||
stubh1.GetCode();
|
||||
InternalArraySingleArgumentConstructorStub stubh2(isolate, kinds[i]);
|
||||
stubh2.GetCode();
|
||||
InternalArrayNArgumentsConstructorStub stubh3(isolate, kinds[i]);
|
||||
stubh3.GetCode();
|
||||
}
|
||||
}
|
||||
|
||||
@ -4367,13 +4324,15 @@ void ArrayConstructorStub::GenerateDispatchToArrayStub(
|
||||
CreateArrayDispatchOneArgument(masm, mode);
|
||||
|
||||
__ bind(¬_one_case);
|
||||
CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
|
||||
ArrayNArgumentsConstructorStub stub(masm->isolate());
|
||||
__ TailCallStub(&stub);
|
||||
} else if (argument_count() == NONE) {
|
||||
CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
|
||||
} else if (argument_count() == ONE) {
|
||||
CreateArrayDispatchOneArgument(masm, mode);
|
||||
} else if (argument_count() == MORE_THAN_ONE) {
|
||||
CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
|
||||
ArrayNArgumentsConstructorStub stub(masm->isolate());
|
||||
__ TailCallStub(&stub);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -4457,7 +4416,7 @@ void InternalArrayConstructorStub::GenerateCase(
|
||||
InternalArrayNoArgumentConstructorStub stub0(isolate(), kind);
|
||||
__ TailCallStub(&stub0, lo, a0, Operand(1));
|
||||
|
||||
InternalArrayNArgumentsConstructorStub stubN(isolate(), kind);
|
||||
ArrayNArgumentsConstructorStub stubN(isolate());
|
||||
__ TailCallStub(&stubN, hi, a0, Operand(1));
|
||||
|
||||
if (IsFastPackedElementsKind(kind)) {
|
||||
|
@ -270,21 +270,13 @@ void ArraySingleArgumentConstructorDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
|
||||
}
|
||||
|
||||
void ArrayConstructorDescriptor::InitializePlatformSpecific(
|
||||
void ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// stack param count needs (constructor pointer, and single argument)
|
||||
Register registers[] = {a1, a2, a0};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
void InternalArrayConstructorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// stack param count needs (constructor pointer, and single argument)
|
||||
Register registers[] = {a1, a0};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void VarArgFunctionDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// stack param count needs (arg count)
|
||||
|
@ -20,45 +20,18 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
#define __ ACCESS_MASM(masm)
|
||||
|
||||
static void InitializeArrayConstructorDescriptor(
|
||||
Isolate* isolate, CodeStubDescriptor* descriptor,
|
||||
int constant_stack_parameter_count) {
|
||||
Address deopt_handler = Runtime::FunctionForId(
|
||||
Runtime::kArrayConstructor)->entry;
|
||||
|
||||
if (constant_stack_parameter_count == 0) {
|
||||
descriptor->Initialize(deopt_handler, constant_stack_parameter_count,
|
||||
JS_FUNCTION_STUB_MODE);
|
||||
} else {
|
||||
descriptor->Initialize(a0, deopt_handler, constant_stack_parameter_count,
|
||||
JS_FUNCTION_STUB_MODE);
|
||||
}
|
||||
void ArrayNArgumentsConstructorStub::Generate(MacroAssembler* masm) {
|
||||
__ dsll(t9, a0, kPointerSizeLog2);
|
||||
__ Daddu(t9, sp, t9);
|
||||
__ sw(a1, MemOperand(t9, 0));
|
||||
__ Push(a1);
|
||||
__ Push(a2);
|
||||
__ Daddu(a0, a0, 3);
|
||||
__ TailCallRuntime(Runtime::kNewArray);
|
||||
}
|
||||
|
||||
|
||||
static void InitializeInternalArrayConstructorDescriptor(
|
||||
Isolate* isolate, CodeStubDescriptor* descriptor,
|
||||
int constant_stack_parameter_count) {
|
||||
Address deopt_handler = Runtime::FunctionForId(
|
||||
Runtime::kInternalArrayConstructor)->entry;
|
||||
|
||||
if (constant_stack_parameter_count == 0) {
|
||||
descriptor->Initialize(deopt_handler, constant_stack_parameter_count,
|
||||
JS_FUNCTION_STUB_MODE);
|
||||
} else {
|
||||
descriptor->Initialize(a0, deopt_handler, constant_stack_parameter_count,
|
||||
JS_FUNCTION_STUB_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ArrayNArgumentsConstructorStub::InitializeDescriptor(
|
||||
CodeStubDescriptor* descriptor) {
|
||||
InitializeArrayConstructorDescriptor(isolate(), descriptor, -1);
|
||||
}
|
||||
|
||||
|
||||
void FastArrayPushStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
|
||||
Address deopt_handler = Runtime::FunctionForId(Runtime::kArrayPush)->entry;
|
||||
descriptor->Initialize(a0, deopt_handler, -1, JS_FUNCTION_STUB_MODE);
|
||||
@ -70,14 +43,6 @@ void FastFunctionBindStub::InitializeDescriptor(
|
||||
descriptor->Initialize(a0, deopt_handler, -1, JS_FUNCTION_STUB_MODE);
|
||||
}
|
||||
|
||||
void InternalArrayNArgumentsConstructorStub::InitializeDescriptor(
|
||||
CodeStubDescriptor* descriptor) {
|
||||
InitializeInternalArrayConstructorDescriptor(isolate(), descriptor, -1);
|
||||
}
|
||||
|
||||
|
||||
#define __ ACCESS_MASM(masm)
|
||||
|
||||
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
||||
Condition cc);
|
||||
static void EmitSmiNonsmiComparison(MacroAssembler* masm,
|
||||
@ -1013,7 +978,7 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
|
||||
CEntryStub::GenerateAheadOfTime(isolate);
|
||||
StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate);
|
||||
StubFailureTrampolineStub::GenerateAheadOfTime(isolate);
|
||||
ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
|
||||
CommonArrayConstructorStub::GenerateStubsAheadOfTime(isolate);
|
||||
CreateAllocationSiteStub::GenerateAheadOfTime(isolate);
|
||||
CreateWeakCellStub::GenerateAheadOfTime(isolate);
|
||||
BinaryOpICStub::GenerateAheadOfTime(isolate);
|
||||
@ -4339,19 +4304,13 @@ static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) {
|
||||
void CommonArrayConstructorStub::GenerateStubsAheadOfTime(Isolate* isolate) {
|
||||
ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>(
|
||||
isolate);
|
||||
ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>(
|
||||
isolate);
|
||||
ArrayConstructorStubAheadOfTimeHelper<ArrayNArgumentsConstructorStub>(
|
||||
isolate);
|
||||
}
|
||||
|
||||
|
||||
void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
|
||||
Isolate* isolate) {
|
||||
ArrayNArgumentsConstructorStub stub(isolate);
|
||||
stub.GetCode();
|
||||
ElementsKind kinds[2] = { FAST_ELEMENTS, FAST_HOLEY_ELEMENTS };
|
||||
for (int i = 0; i < 2; i++) {
|
||||
// For internal arrays we only need a few things.
|
||||
@ -4359,8 +4318,6 @@ void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
|
||||
stubh1.GetCode();
|
||||
InternalArraySingleArgumentConstructorStub stubh2(isolate, kinds[i]);
|
||||
stubh2.GetCode();
|
||||
InternalArrayNArgumentsConstructorStub stubh3(isolate, kinds[i]);
|
||||
stubh3.GetCode();
|
||||
}
|
||||
}
|
||||
|
||||
@ -4379,13 +4336,15 @@ void ArrayConstructorStub::GenerateDispatchToArrayStub(
|
||||
CreateArrayDispatchOneArgument(masm, mode);
|
||||
|
||||
__ bind(¬_one_case);
|
||||
CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
|
||||
ArrayNArgumentsConstructorStub stub(masm->isolate());
|
||||
__ TailCallStub(&stub);
|
||||
} else if (argument_count() == NONE) {
|
||||
CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
|
||||
} else if (argument_count() == ONE) {
|
||||
CreateArrayDispatchOneArgument(masm, mode);
|
||||
} else if (argument_count() == MORE_THAN_ONE) {
|
||||
CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
|
||||
ArrayNArgumentsConstructorStub stub(masm->isolate());
|
||||
__ TailCallStub(&stub);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -4469,7 +4428,7 @@ void InternalArrayConstructorStub::GenerateCase(
|
||||
InternalArrayNoArgumentConstructorStub stub0(isolate(), kind);
|
||||
__ TailCallStub(&stub0, lo, a0, Operand(1));
|
||||
|
||||
InternalArrayNArgumentsConstructorStub stubN(isolate(), kind);
|
||||
ArrayNArgumentsConstructorStub stubN(isolate());
|
||||
__ TailCallStub(&stubN, hi, a0, Operand(1));
|
||||
|
||||
if (IsFastPackedElementsKind(kind)) {
|
||||
|
@ -270,21 +270,13 @@ void ArraySingleArgumentConstructorDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
|
||||
}
|
||||
|
||||
void ArrayConstructorDescriptor::InitializePlatformSpecific(
|
||||
void ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// stack param count needs (constructor pointer, and single argument)
|
||||
Register registers[] = {a1, a2, a0};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
void InternalArrayConstructorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// stack param count needs (constructor pointer, and single argument)
|
||||
Register registers[] = {a1, a0};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void VarArgFunctionDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// stack param count needs (arg count)
|
||||
|
@ -322,7 +322,6 @@ Object* ArrayConstructorCommon(Isolate* isolate, Handle<JSFunction> constructor,
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_NewArray) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_LE(3, args.length());
|
||||
@ -339,72 +338,6 @@ RUNTIME_FUNCTION(Runtime_NewArray) {
|
||||
return ArrayConstructorCommon(isolate, constructor, new_target, site, &argv);
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_ArrayConstructor) {
|
||||
HandleScope scope(isolate);
|
||||
// If we get 2 arguments then they are the stub parameters (constructor, type
|
||||
// info). If we get 4, then the first one is a pointer to the arguments
|
||||
// passed by the caller, and the last one is the length of the arguments
|
||||
// passed to the caller (redundant, but useful to check on the deoptimizer
|
||||
// with an assert).
|
||||
Arguments empty_args(0, NULL);
|
||||
bool no_caller_args = args.length() == 2;
|
||||
DCHECK(no_caller_args || args.length() == 4);
|
||||
int parameters_start = no_caller_args ? 0 : 1;
|
||||
Arguments* caller_args =
|
||||
no_caller_args ? &empty_args : reinterpret_cast<Arguments*>(args[0]);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
|
||||
CONVERT_ARG_HANDLE_CHECKED(Object, type_info, parameters_start + 1);
|
||||
#ifdef DEBUG
|
||||
if (!no_caller_args) {
|
||||
CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 2);
|
||||
DCHECK(arg_count == caller_args->length());
|
||||
}
|
||||
#endif
|
||||
|
||||
Handle<AllocationSite> site;
|
||||
if (!type_info.is_null() && !type_info->IsUndefined(isolate)) {
|
||||
site = Handle<AllocationSite>::cast(type_info);
|
||||
DCHECK(!site->SitePointsToLiteral());
|
||||
}
|
||||
|
||||
return ArrayConstructorCommon(isolate, constructor, constructor, site,
|
||||
caller_args);
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_InternalArrayConstructor) {
|
||||
HandleScope scope(isolate);
|
||||
Arguments empty_args(0, NULL);
|
||||
bool no_caller_args = args.length() == 1;
|
||||
DCHECK(no_caller_args || args.length() == 3);
|
||||
int parameters_start = no_caller_args ? 0 : 1;
|
||||
Arguments* caller_args =
|
||||
no_caller_args ? &empty_args : reinterpret_cast<Arguments*>(args[0]);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
|
||||
#ifdef DEBUG
|
||||
if (!no_caller_args) {
|
||||
CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 1);
|
||||
DCHECK(arg_count == caller_args->length());
|
||||
}
|
||||
#endif
|
||||
return ArrayConstructorCommon(isolate, constructor, constructor,
|
||||
Handle<AllocationSite>::null(), caller_args);
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_ArraySingleArgumentConstructor) {
|
||||
HandleScope scope(isolate);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0);
|
||||
Object** argument_base = reinterpret_cast<Object**>(args[1]);
|
||||
CONVERT_SMI_ARG_CHECKED(argument_count, 2);
|
||||
CONVERT_ARG_HANDLE_CHECKED(Object, raw_site, 3);
|
||||
Handle<AllocationSite> casted_site =
|
||||
raw_site->IsUndefined(isolate) ? Handle<AllocationSite>::null()
|
||||
: Handle<AllocationSite>::cast(raw_site);
|
||||
Arguments constructor_args(argument_count, argument_base);
|
||||
return ArrayConstructorCommon(isolate, constructor, constructor, casted_site,
|
||||
&constructor_args);
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_NormalizeElements) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK(args.length() == 1);
|
||||
|
@ -31,29 +31,26 @@ namespace internal {
|
||||
|
||||
// Entries have the form F(name, number of arguments, number of values):
|
||||
|
||||
#define FOR_EACH_INTRINSIC_ARRAY(F) \
|
||||
F(FinishArrayPrototypeSetup, 1, 1) \
|
||||
F(SpecialArrayFunctions, 0, 1) \
|
||||
F(TransitionElementsKind, 2, 1) \
|
||||
F(RemoveArrayHoles, 2, 1) \
|
||||
F(MoveArrayContents, 2, 1) \
|
||||
F(EstimateNumberOfElements, 1, 1) \
|
||||
F(GetArrayKeys, 2, 1) \
|
||||
F(ArrayConstructor, -1, 1) \
|
||||
F(NewArray, -1 /* >= 3 */, 1) \
|
||||
F(InternalArrayConstructor, -1, 1) \
|
||||
F(ArraySingleArgumentConstructor, -1, 1) \
|
||||
F(ArrayPush, -1, 1) \
|
||||
F(FunctionBind, -1, 1) \
|
||||
F(NormalizeElements, 1, 1) \
|
||||
F(GrowArrayElements, 2, 1) \
|
||||
F(HasComplexElements, 1, 1) \
|
||||
F(IsArray, 1, 1) \
|
||||
F(ArrayIsArray, 1, 1) \
|
||||
F(HasCachedArrayIndex, 1, 1) \
|
||||
F(GetCachedArrayIndex, 1, 1) \
|
||||
F(FixedArrayGet, 2, 1) \
|
||||
F(FixedArraySet, 3, 1) \
|
||||
#define FOR_EACH_INTRINSIC_ARRAY(F) \
|
||||
F(FinishArrayPrototypeSetup, 1, 1) \
|
||||
F(SpecialArrayFunctions, 0, 1) \
|
||||
F(TransitionElementsKind, 2, 1) \
|
||||
F(RemoveArrayHoles, 2, 1) \
|
||||
F(MoveArrayContents, 2, 1) \
|
||||
F(EstimateNumberOfElements, 1, 1) \
|
||||
F(GetArrayKeys, 2, 1) \
|
||||
F(NewArray, -1 /* >= 3 */, 1) \
|
||||
F(ArrayPush, -1, 1) \
|
||||
F(FunctionBind, -1, 1) \
|
||||
F(NormalizeElements, 1, 1) \
|
||||
F(GrowArrayElements, 2, 1) \
|
||||
F(HasComplexElements, 1, 1) \
|
||||
F(IsArray, 1, 1) \
|
||||
F(ArrayIsArray, 1, 1) \
|
||||
F(HasCachedArrayIndex, 1, 1) \
|
||||
F(GetCachedArrayIndex, 1, 1) \
|
||||
F(FixedArrayGet, 2, 1) \
|
||||
F(FixedArraySet, 3, 1) \
|
||||
F(ArraySpeciesConstructor, 1, 1)
|
||||
|
||||
#define FOR_EACH_INTRINSIC_ATOMICS(F) \
|
||||
|
@ -20,45 +20,18 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
#define __ ACCESS_MASM(masm)
|
||||
|
||||
static void InitializeArrayConstructorDescriptor(
|
||||
Isolate* isolate, CodeStubDescriptor* descriptor,
|
||||
int constant_stack_parameter_count) {
|
||||
Address deopt_handler = Runtime::FunctionForId(
|
||||
Runtime::kArrayConstructor)->entry;
|
||||
|
||||
if (constant_stack_parameter_count == 0) {
|
||||
descriptor->Initialize(deopt_handler, constant_stack_parameter_count,
|
||||
JS_FUNCTION_STUB_MODE);
|
||||
} else {
|
||||
descriptor->Initialize(rax, deopt_handler, constant_stack_parameter_count,
|
||||
JS_FUNCTION_STUB_MODE);
|
||||
}
|
||||
void ArrayNArgumentsConstructorStub::Generate(MacroAssembler* masm) {
|
||||
__ popq(rcx);
|
||||
__ movq(MemOperand(rsp, rax, times_8, 0), rdi);
|
||||
__ pushq(rdi);
|
||||
__ pushq(rbx);
|
||||
__ pushq(rcx);
|
||||
__ addq(rax, Immediate(3));
|
||||
__ TailCallRuntime(Runtime::kNewArray);
|
||||
}
|
||||
|
||||
|
||||
static void InitializeInternalArrayConstructorDescriptor(
|
||||
Isolate* isolate, CodeStubDescriptor* descriptor,
|
||||
int constant_stack_parameter_count) {
|
||||
Address deopt_handler = Runtime::FunctionForId(
|
||||
Runtime::kInternalArrayConstructor)->entry;
|
||||
|
||||
if (constant_stack_parameter_count == 0) {
|
||||
descriptor->Initialize(deopt_handler, constant_stack_parameter_count,
|
||||
JS_FUNCTION_STUB_MODE);
|
||||
} else {
|
||||
descriptor->Initialize(rax, deopt_handler, constant_stack_parameter_count,
|
||||
JS_FUNCTION_STUB_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ArrayNArgumentsConstructorStub::InitializeDescriptor(
|
||||
CodeStubDescriptor* descriptor) {
|
||||
InitializeArrayConstructorDescriptor(isolate(), descriptor, -1);
|
||||
}
|
||||
|
||||
|
||||
void FastArrayPushStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
|
||||
Address deopt_handler = Runtime::FunctionForId(Runtime::kArrayPush)->entry;
|
||||
descriptor->Initialize(rax, deopt_handler, -1, JS_FUNCTION_STUB_MODE);
|
||||
@ -70,15 +43,6 @@ void FastFunctionBindStub::InitializeDescriptor(
|
||||
descriptor->Initialize(rax, deopt_handler, -1, JS_FUNCTION_STUB_MODE);
|
||||
}
|
||||
|
||||
void InternalArrayNArgumentsConstructorStub::InitializeDescriptor(
|
||||
CodeStubDescriptor* descriptor) {
|
||||
InitializeInternalArrayConstructorDescriptor(isolate(), descriptor, -1);
|
||||
}
|
||||
|
||||
|
||||
#define __ ACCESS_MASM(masm)
|
||||
|
||||
|
||||
void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm,
|
||||
ExternalReference miss) {
|
||||
// Update the static counter each time a new code stub is generated.
|
||||
@ -1661,7 +1625,7 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
|
||||
StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate);
|
||||
StubFailureTrampolineStub::GenerateAheadOfTime(isolate);
|
||||
// It is important that the store buffer overflow stubs are generated first.
|
||||
ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
|
||||
CommonArrayConstructorStub::GenerateStubsAheadOfTime(isolate);
|
||||
CreateAllocationSiteStub::GenerateAheadOfTime(isolate);
|
||||
CreateWeakCellStub::GenerateAheadOfTime(isolate);
|
||||
BinaryOpICStub::GenerateAheadOfTime(isolate);
|
||||
@ -3992,19 +3956,14 @@ static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) {
|
||||
void CommonArrayConstructorStub::GenerateStubsAheadOfTime(Isolate* isolate) {
|
||||
ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>(
|
||||
isolate);
|
||||
ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>(
|
||||
isolate);
|
||||
ArrayConstructorStubAheadOfTimeHelper<ArrayNArgumentsConstructorStub>(
|
||||
isolate);
|
||||
}
|
||||
ArrayNArgumentsConstructorStub stub(isolate);
|
||||
stub.GetCode();
|
||||
|
||||
|
||||
void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
|
||||
Isolate* isolate) {
|
||||
ElementsKind kinds[2] = { FAST_ELEMENTS, FAST_HOLEY_ELEMENTS };
|
||||
for (int i = 0; i < 2; i++) {
|
||||
// For internal arrays we only need a few things
|
||||
@ -4012,8 +3971,6 @@ void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
|
||||
stubh1.GetCode();
|
||||
InternalArraySingleArgumentConstructorStub stubh2(isolate, kinds[i]);
|
||||
stubh2.GetCode();
|
||||
InternalArrayNArgumentsConstructorStub stubh3(isolate, kinds[i]);
|
||||
stubh3.GetCode();
|
||||
}
|
||||
}
|
||||
|
||||
@ -4033,13 +3990,15 @@ void ArrayConstructorStub::GenerateDispatchToArrayStub(
|
||||
CreateArrayDispatchOneArgument(masm, mode);
|
||||
|
||||
__ bind(¬_one_case);
|
||||
CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
|
||||
ArrayNArgumentsConstructorStub stub(masm->isolate());
|
||||
__ TailCallStub(&stub);
|
||||
} else if (argument_count() == NONE) {
|
||||
CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
|
||||
} else if (argument_count() == ONE) {
|
||||
CreateArrayDispatchOneArgument(masm, mode);
|
||||
} else if (argument_count() == MORE_THAN_ONE) {
|
||||
CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
|
||||
ArrayNArgumentsConstructorStub stub(masm->isolate());
|
||||
__ TailCallStub(&stub);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -4158,7 +4117,7 @@ void InternalArrayConstructorStub::GenerateCase(
|
||||
__ TailCallStub(&stub1);
|
||||
|
||||
__ bind(¬_one_case);
|
||||
InternalArrayNArgumentsConstructorStub stubN(isolate(), kind);
|
||||
ArrayNArgumentsConstructorStub stubN(isolate());
|
||||
__ TailCallStub(&stubN);
|
||||
}
|
||||
|
||||
|
@ -266,19 +266,14 @@ void ArraySingleArgumentConstructorDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
|
||||
}
|
||||
|
||||
void ArrayConstructorDescriptor::InitializePlatformSpecific(
|
||||
void ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// stack param count needs (constructor pointer, and single argument)
|
||||
// register state
|
||||
// rax -- number of arguments
|
||||
// rdi -- function
|
||||
// rbx -- allocation site with elements kind
|
||||
Register registers[] = {rdi, rbx, rax};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
void InternalArrayConstructorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// stack param count needs (constructor pointer, and single argument)
|
||||
Register registers[] = {rdi, rax};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
|
||||
}
|
||||
|
||||
void VarArgFunctionDescriptor::InitializePlatformSpecific(
|
||||
|
Loading…
Reference in New Issue
Block a user