Commit 855b88ae authored by Benedikt Meurer's avatar Benedikt Meurer Committed by Commit Bot

[turbofan] Properly optimize literals in inlined functions.

When inlining based on SharedFunctionInfo rather than based on concrete
JSFunction, we weren't able to properly optimize array, object and
regexp literals inside the inlinee, because we didn't know the concrete
FeedbackVector for the inlinee inside JSCreateLowering. This was because
JSCreateLowering wasn't properly updated after the literals moved to the
FeedbackVector. Now with this CL we also have the VectorSlotPair on the
literal creation operators, just like we do for property accesses and
calls, and are thus able to always access the appropriate FeedbackVector
and optimize the literal creation.

The impact is illustrated by the micro-benchmark on the tracking bug,
which goes from

  createEmptyArrayLiteral: 1846 ms.
  createShallowArrayLiteral: 1868 ms.
  createShallowObjectLiteral: 2246 ms.

to

  createEmptyArrayLiteral: 1175 ms.
  createShallowArrayLiteral: 1187 ms.
  createShallowObjectLiteral: 1195 ms.

with this CL, so up to 2x faster now.

Drive-by-fix: Also remove the unused CreateEmptyObjectLiteral builtin
and cleanup the names of the other builtins to be consistent with the
names of the TurboFan operators and Ignition bytecodes.

Bug: v8:6856
Change-Id: I453828d019b27c9aa1344edac0dd84e91a457097
Reviewed-on: https://chromium-review.googlesource.com/680656
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48140}
parent 63f9ee16
...@@ -90,27 +90,6 @@ void TypeofDescriptor::InitializePlatformSpecific( ...@@ -90,27 +90,6 @@ void TypeofDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void FastCloneRegExpDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {r3, r2, r1, r0};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {r3, r2, r1};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {r3, r2, r1, r0};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void CallFunctionDescriptor::InitializePlatformSpecific( void CallFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = {r1}; Register registers[] = {r1};
......
...@@ -92,38 +92,6 @@ void TypeofDescriptor::InitializePlatformSpecific( ...@@ -92,38 +92,6 @@ void TypeofDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void FastCloneRegExpDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// x3: closure
// x2: object literal index
// x1: constant properties
// x0: object literal flags
Register registers[] = {x3, x2, x1, x0};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// x3: closure
// x2: array literal index
// x1: constant elements
Register registers[] = {x3, x2, x1};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
// x3: closure
// x2: object literal index
// x1: constant properties
// x0: object literal flags
Register registers[] = {x3, x2, x1, x0};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void CallFunctionDescriptor::InitializePlatformSpecific( void CallFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
// x1 function the function to call // x1 function the function to call
......
...@@ -634,7 +634,7 @@ void ObjectLiteral::BuildConstantProperties(Isolate* isolate) { ...@@ -634,7 +634,7 @@ void ObjectLiteral::BuildConstantProperties(Isolate* isolate) {
} }
bool ObjectLiteral::IsFastCloningSupported() const { bool ObjectLiteral::IsFastCloningSupported() const {
// The FastCloneShallowObject builtin doesn't copy elements, and object // The CreateShallowObjectLiteratal builtin doesn't copy elements, and object
// literals don't support copy-on-write (COW) elements for now. // literals don't support copy-on-write (COW) elements for now.
// TODO(mvstanton): make object literals support COW elements. // TODO(mvstanton): make object literals support COW elements.
return fast_elements() && is_shallow() && return fast_elements() && is_shallow() &&
......
...@@ -1321,7 +1321,7 @@ class ObjectLiteral final : public AggregateLiteral { ...@@ -1321,7 +1321,7 @@ class ObjectLiteral final : public AggregateLiteral {
// marked expressions, no store code is emitted. // marked expressions, no store code is emitted.
void CalculateEmitStore(Zone* zone); void CalculateEmitStore(Zone* zone);
// Determines whether the {FastCloneShallowObject} builtin can be used. // Determines whether the {CreateShallowObjectLiteratal} builtin can be used.
bool IsFastCloningSupported() const; bool IsFastCloningSupported() const;
// Assemble bitfield of flags for the CreateObjectLiteral helper. // Assemble bitfield of flags for the CreateObjectLiteral helper.
...@@ -1449,7 +1449,7 @@ class ArrayLiteral final : public AggregateLiteral { ...@@ -1449,7 +1449,7 @@ class ArrayLiteral final : public AggregateLiteral {
// Populate the constant elements fixed array. // Populate the constant elements fixed array.
void BuildConstantElements(Isolate* isolate); void BuildConstantElements(Isolate* isolate);
// Determines whether the {FastCloneShallowArray} builtin can be used. // Determines whether the {CreateShallowArrayLiteral} builtin can be used.
bool IsFastCloningSupported() const; bool IsFastCloningSupported() const;
// Assemble bitfield of flags for the CreateArrayLiteral helper. // Assemble bitfield of flags for the CreateArrayLiteral helper.
......
...@@ -334,17 +334,14 @@ TF_BUILTIN(FastNewFunctionContextFunction, ConstructorBuiltinsAssembler) { ...@@ -334,17 +334,14 @@ TF_BUILTIN(FastNewFunctionContextFunction, ConstructorBuiltinsAssembler) {
ScopeType::FUNCTION_SCOPE)); ScopeType::FUNCTION_SCOPE));
} }
Node* ConstructorBuiltinsAssembler::EmitFastCloneRegExp(Node* closure, Node* ConstructorBuiltinsAssembler::EmitCreateRegExpLiteral(
Node* literal_index, Node* feedback_vector, Node* slot, Node* pattern, Node* flags,
Node* pattern,
Node* flags,
Node* context) { Node* context) {
Label call_runtime(this, Label::kDeferred), end(this); Label call_runtime(this, Label::kDeferred), end(this);
VARIABLE(result, MachineRepresentation::kTagged); VARIABLE(result, MachineRepresentation::kTagged);
Node* feedback_vector = LoadFeedbackVector(closure);
Node* literal_site = Node* literal_site =
LoadFeedbackVectorSlot(feedback_vector, literal_index, 0, SMI_PARAMETERS); LoadFeedbackVectorSlot(feedback_vector, slot, 0, INTPTR_PARAMETERS);
GotoIf(NotHasBoilerplate(literal_site), &call_runtime); GotoIf(NotHasBoilerplate(literal_site), &call_runtime);
{ {
Node* boilerplate = literal_site; Node* boilerplate = literal_site;
...@@ -361,8 +358,8 @@ Node* ConstructorBuiltinsAssembler::EmitFastCloneRegExp(Node* closure, ...@@ -361,8 +358,8 @@ Node* ConstructorBuiltinsAssembler::EmitFastCloneRegExp(Node* closure,
BIND(&call_runtime); BIND(&call_runtime);
{ {
result.Bind(CallRuntime(Runtime::kCreateRegExpLiteral, context, closure, result.Bind(CallRuntime(Runtime::kCreateRegExpLiteral, context,
literal_index, pattern, flags)); feedback_vector, SmiTag(slot), pattern, flags));
Goto(&end); Goto(&end);
} }
...@@ -370,14 +367,15 @@ Node* ConstructorBuiltinsAssembler::EmitFastCloneRegExp(Node* closure, ...@@ -370,14 +367,15 @@ Node* ConstructorBuiltinsAssembler::EmitFastCloneRegExp(Node* closure,
return result.value(); return result.value();
} }
TF_BUILTIN(FastCloneRegExp, ConstructorBuiltinsAssembler) { TF_BUILTIN(CreateRegExpLiteral, ConstructorBuiltinsAssembler) {
Node* closure = Parameter(FastCloneRegExpDescriptor::kClosure); Node* feedback_vector = Parameter(Descriptor::kFeedbackVector);
Node* literal_index = Parameter(FastCloneRegExpDescriptor::kLiteralIndex); Node* slot = SmiUntag(Parameter(Descriptor::kSlot));
Node* pattern = Parameter(FastCloneRegExpDescriptor::kPattern); Node* pattern = Parameter(Descriptor::kPattern);
Node* flags = Parameter(FastCloneRegExpDescriptor::kFlags); Node* flags = Parameter(Descriptor::kFlags);
Node* context = Parameter(FastCloneRegExpDescriptor::kContext); Node* context = Parameter(Descriptor::kContext);
Node* result =
Return(EmitFastCloneRegExp(closure, literal_index, pattern, flags, context)); EmitCreateRegExpLiteral(feedback_vector, slot, pattern, flags, context);
Return(result);
} }
Node* ConstructorBuiltinsAssembler::NonEmptyShallowClone( Node* ConstructorBuiltinsAssembler::NonEmptyShallowClone(
...@@ -402,16 +400,15 @@ Node* ConstructorBuiltinsAssembler::NonEmptyShallowClone( ...@@ -402,16 +400,15 @@ Node* ConstructorBuiltinsAssembler::NonEmptyShallowClone(
return array; return array;
} }
Node* ConstructorBuiltinsAssembler::EmitFastCloneShallowArray( Node* ConstructorBuiltinsAssembler::EmitCreateShallowArrayLiteral(
Node* closure, Node* literal_index, Node* context, Label* call_runtime, Node* feedback_vector, Node* slot, Node* context, Label* call_runtime,
AllocationSiteMode allocation_site_mode) { AllocationSiteMode allocation_site_mode) {
Label zero_capacity(this), cow_elements(this), fast_elements(this), Label zero_capacity(this), cow_elements(this), fast_elements(this),
return_result(this); return_result(this);
VARIABLE(result, MachineRepresentation::kTagged); VARIABLE(result, MachineRepresentation::kTagged);
Node* feedback_vector = LoadFeedbackVector(closure);
Node* allocation_site = Node* allocation_site =
LoadFeedbackVectorSlot(feedback_vector, literal_index, 0, SMI_PARAMETERS); LoadFeedbackVectorSlot(feedback_vector, slot, 0, INTPTR_PARAMETERS);
GotoIf(NotHasBoilerplate(allocation_site), call_runtime); GotoIf(NotHasBoilerplate(allocation_site), call_runtime);
Node* boilerplate = LoadAllocationSiteBoilerplate(allocation_site); Node* boilerplate = LoadAllocationSiteBoilerplate(allocation_site);
...@@ -484,49 +481,32 @@ Node* ConstructorBuiltinsAssembler::EmitFastCloneShallowArray( ...@@ -484,49 +481,32 @@ Node* ConstructorBuiltinsAssembler::EmitFastCloneShallowArray(
return result.value(); return result.value();
} }
void ConstructorBuiltinsAssembler::CreateFastCloneShallowArrayBuiltin( TF_BUILTIN(CreateShallowArrayLiteral, ConstructorBuiltinsAssembler) {
AllocationSiteMode allocation_site_mode) { Node* feedback_vector = Parameter(Descriptor::kFeedbackVector);
Node* closure = Parameter(FastCloneShallowArrayDescriptor::kClosure); Node* slot = SmiUntag(Parameter(Descriptor::kSlot));
Node* literal_index = Node* constant_elements = Parameter(Descriptor::kConstantElements);
Parameter(FastCloneShallowArrayDescriptor::kLiteralIndex); Node* context = Parameter(Descriptor::kContext);
Node* constant_elements =
Parameter(FastCloneShallowArrayDescriptor::kConstantElements);
Node* context = Parameter(FastCloneShallowArrayDescriptor::kContext);
Label call_runtime(this, Label::kDeferred); Label call_runtime(this, Label::kDeferred);
Return(EmitFastCloneShallowArray(closure, literal_index, context, Return(EmitCreateShallowArrayLiteral(feedback_vector, slot, context,
&call_runtime, allocation_site_mode)); &call_runtime,
DONT_TRACK_ALLOCATION_SITE));
BIND(&call_runtime); BIND(&call_runtime);
{ {
Comment("call runtime"); Comment("call runtime");
int flags = AggregateLiteral::kIsShallow; int const flags =
if (allocation_site_mode == TRACK_ALLOCATION_SITE) { AggregateLiteral::kDisableMementos | AggregateLiteral::kIsShallow;
// Force initial allocation sites on the initial literal setup step. Return(CallRuntime(Runtime::kCreateArrayLiteral, context, feedback_vector,
flags |= AggregateLiteral::kNeedsInitialAllocationSite; SmiTag(slot), constant_elements, SmiConstant(flags)));
} else {
flags |= AggregateLiteral::kDisableMementos;
}
Return(CallRuntime(Runtime::kCreateArrayLiteral, context, closure,
literal_index, constant_elements, SmiConstant(flags)));
} }
} }
TF_BUILTIN(FastCloneShallowArrayTrack, ConstructorBuiltinsAssembler) {
CreateFastCloneShallowArrayBuiltin(TRACK_ALLOCATION_SITE);
}
TF_BUILTIN(FastCloneShallowArrayDontTrack, ConstructorBuiltinsAssembler) {
CreateFastCloneShallowArrayBuiltin(DONT_TRACK_ALLOCATION_SITE);
}
Node* ConstructorBuiltinsAssembler::EmitCreateEmptyArrayLiteral( Node* ConstructorBuiltinsAssembler::EmitCreateEmptyArrayLiteral(
Node* closure, Node* literal_index, Node* context) { Node* feedback_vector, Node* slot, Node* context) {
// Array literals always have a valid AllocationSite to properly track // Array literals always have a valid AllocationSite to properly track
// elements transitions. // elements transitions.
Node* feedback_vector = LoadFeedbackVector(closure);
VARIABLE(allocation_site, MachineRepresentation::kTagged, VARIABLE(allocation_site, MachineRepresentation::kTagged,
LoadFeedbackVectorSlot(feedback_vector, literal_index, 0, LoadFeedbackVectorSlot(feedback_vector, slot, 0, INTPTR_PARAMETERS));
SMI_PARAMETERS));
Label create_empty_array(this), Label create_empty_array(this),
initialize_allocation_site(this, Label::kDeferred), done(this); initialize_allocation_site(this, Label::kDeferred), done(this);
...@@ -537,7 +517,7 @@ Node* ConstructorBuiltinsAssembler::EmitCreateEmptyArrayLiteral( ...@@ -537,7 +517,7 @@ Node* ConstructorBuiltinsAssembler::EmitCreateEmptyArrayLiteral(
BIND(&initialize_allocation_site); BIND(&initialize_allocation_site);
{ {
allocation_site.Bind( allocation_site.Bind(
CreateAllocationSiteInFeedbackVector(feedback_vector, literal_index)); CreateAllocationSiteInFeedbackVector(feedback_vector, SmiTag(slot)));
Goto(&create_empty_array); Goto(&create_empty_array);
} }
...@@ -563,18 +543,17 @@ Node* ConstructorBuiltinsAssembler::EmitCreateEmptyArrayLiteral( ...@@ -563,18 +543,17 @@ Node* ConstructorBuiltinsAssembler::EmitCreateEmptyArrayLiteral(
} }
TF_BUILTIN(CreateEmptyArrayLiteral, ConstructorBuiltinsAssembler) { TF_BUILTIN(CreateEmptyArrayLiteral, ConstructorBuiltinsAssembler) {
Node* closure = Parameter(Descriptor::kClosure); Node* feedback_vector = Parameter(Descriptor::kFeedbackVector);
Node* literal_index = Parameter(Descriptor::kLiteralIndex); Node* slot = SmiUntag(Parameter(Descriptor::kSlot));
Node* context = Parameter(Descriptor::kContext); Node* context = Parameter(Descriptor::kContext);
Node* result = EmitCreateEmptyArrayLiteral(closure, literal_index, context); Node* result = EmitCreateEmptyArrayLiteral(feedback_vector, slot, context);
Return(result); Return(result);
} }
Node* ConstructorBuiltinsAssembler::EmitFastCloneShallowObject( Node* ConstructorBuiltinsAssembler::EmitCreateShallowObjectLiteral(
Label* call_runtime, Node* closure, Node* literals_index) { Node* feedback_vector, Node* slot, Label* call_runtime) {
Node* feedback_vector = LoadFeedbackVector(closure); Node* allocation_site =
Node* allocation_site = LoadFeedbackVectorSlot( LoadFeedbackVectorSlot(feedback_vector, slot, 0, INTPTR_PARAMETERS);
feedback_vector, literals_index, 0, SMI_PARAMETERS);
GotoIf(NotHasBoilerplate(allocation_site), call_runtime); GotoIf(NotHasBoilerplate(allocation_site), call_runtime);
Node* boilerplate = LoadAllocationSiteBoilerplate(allocation_site); Node* boilerplate = LoadAllocationSiteBoilerplate(allocation_site);
...@@ -730,12 +709,12 @@ Node* ConstructorBuiltinsAssembler::EmitFastCloneShallowObject( ...@@ -730,12 +709,12 @@ Node* ConstructorBuiltinsAssembler::EmitFastCloneShallowObject(
return copy; return copy;
} }
TF_BUILTIN(FastCloneShallowObject, ConstructorBuiltinsAssembler) { TF_BUILTIN(CreateShallowObjectLiteral, ConstructorBuiltinsAssembler) {
Label call_runtime(this); Label call_runtime(this);
Node* closure = Parameter(Descriptor::kClosure); Node* feedback_vector = Parameter(Descriptor::kFeedbackVector);
Node* literals_index = Parameter(Descriptor::kLiteralIndex); Node* slot = SmiUntag(Parameter(Descriptor::kSlot));
Node* copy = Node* copy =
EmitFastCloneShallowObject(&call_runtime, closure, literals_index); EmitCreateShallowObjectLiteral(feedback_vector, slot, &call_runtime);
Return(copy); Return(copy);
BIND(&call_runtime); BIND(&call_runtime);
...@@ -743,11 +722,11 @@ TF_BUILTIN(FastCloneShallowObject, ConstructorBuiltinsAssembler) { ...@@ -743,11 +722,11 @@ TF_BUILTIN(FastCloneShallowObject, ConstructorBuiltinsAssembler) {
Parameter(Descriptor::kBoilerplateDescription); Parameter(Descriptor::kBoilerplateDescription);
Node* flags = Parameter(Descriptor::kFlags); Node* flags = Parameter(Descriptor::kFlags);
Node* context = Parameter(Descriptor::kContext); Node* context = Parameter(Descriptor::kContext);
TailCallRuntime(Runtime::kCreateObjectLiteral, context, closure, TailCallRuntime(Runtime::kCreateObjectLiteral, context, feedback_vector,
literals_index, boilerplate_description, flags); SmiTag(slot), boilerplate_description, flags);
} }
// Used by the CreateEmptyObjectLiteral stub and bytecode. // Used by the CreateEmptyObjectLiteral bytecode and the Object constructor.
Node* ConstructorBuiltinsAssembler::EmitCreateEmptyObjectLiteral( Node* ConstructorBuiltinsAssembler::EmitCreateEmptyObjectLiteral(
Node* context) { Node* context) {
Node* native_context = LoadNativeContext(context); Node* native_context = LoadNativeContext(context);
...@@ -766,12 +745,6 @@ Node* ConstructorBuiltinsAssembler::EmitCreateEmptyObjectLiteral( ...@@ -766,12 +745,6 @@ Node* ConstructorBuiltinsAssembler::EmitCreateEmptyObjectLiteral(
return result; return result;
} }
TF_BUILTIN(CreateEmptyObjectLiteral, ConstructorBuiltinsAssembler) {
Node* context = Parameter(Descriptor::kContext);
Node* result = EmitCreateEmptyObjectLiteral(context);
Return(result);
}
TF_BUILTIN(ObjectConstructor, ConstructorBuiltinsAssembler) { TF_BUILTIN(ObjectConstructor, ConstructorBuiltinsAssembler) {
int const kValueArg = 0; int const kValueArg = 0;
Node* argc = Node* argc =
......
...@@ -20,19 +20,17 @@ class ConstructorBuiltinsAssembler : public CodeStubAssembler { ...@@ -20,19 +20,17 @@ class ConstructorBuiltinsAssembler : public CodeStubAssembler {
Node* EmitFastNewFunctionContext(Node* closure, Node* slots, Node* context, Node* EmitFastNewFunctionContext(Node* closure, Node* slots, Node* context,
ScopeType scope_type); ScopeType scope_type);
Node* EmitFastCloneRegExp(Node* closure, Node* literal_index, Node* pattern, Node* EmitCreateRegExpLiteral(Node* feedback_vector, Node* slot,
Node* flags, Node* context); Node* pattern, Node* flags, Node* context);
Node* EmitFastCloneShallowArray(Node* closure, Node* literal_index, Node* EmitCreateShallowArrayLiteral(Node* feedback_vector, Node* slot,
Node* context, Label* call_runtime, Node* context, Label* call_runtime,
AllocationSiteMode allocation_site_mode); AllocationSiteMode allocation_site_mode);
Node* EmitCreateEmptyArrayLiteral(Node* closure, Node* iteral_index, Node* EmitCreateEmptyArrayLiteral(Node* feedback_vector, Node* slot,
Node* context); Node* context);
void CreateFastCloneShallowArrayBuiltin(
AllocationSiteMode allocation_site_mode);
Node* EmitFastCloneShallowObject(Label* call_runtime, Node* closure, Node* EmitCreateShallowObjectLiteral(Node* feedback_vector, Node* slot,
Node* literals_index); Label* call_runtime);
Node* EmitCreateEmptyObjectLiteral(Node* context); Node* EmitCreateEmptyObjectLiteral(Node* context);
Node* EmitFastNewObject(Node* context, Node* target, Node* new_target); Node* EmitFastNewObject(Node* context, Node* target, Node* new_target);
......
...@@ -73,12 +73,11 @@ namespace internal { ...@@ -73,12 +73,11 @@ namespace internal {
TFC(FastNewClosure, FastNewClosure, 1) \ TFC(FastNewClosure, FastNewClosure, 1) \
TFC(FastNewFunctionContextEval, FastNewFunctionContext, 1) \ TFC(FastNewFunctionContextEval, FastNewFunctionContext, 1) \
TFC(FastNewFunctionContextFunction, FastNewFunctionContext, 1) \ TFC(FastNewFunctionContextFunction, FastNewFunctionContext, 1) \
TFC(FastCloneRegExp, FastCloneRegExp, 1) \ TFS(CreateRegExpLiteral, kFeedbackVector, kSlot, kPattern, kFlags) \
TFC(FastCloneShallowArrayTrack, FastCloneShallowArray, 1) \ TFS(CreateEmptyArrayLiteral, kFeedbackVector, kSlot) \
TFC(FastCloneShallowArrayDontTrack, FastCloneShallowArray, 1) \ TFS(CreateShallowArrayLiteral, kFeedbackVector, kSlot, kConstantElements) \
TFS(CreateEmptyArrayLiteral, kClosure, kLiteralIndex) \ TFS(CreateShallowObjectLiteral, kFeedbackVector, kSlot, \
TFS(CreateEmptyObjectLiteral, kClosure) \ kBoilerplateDescription, kFlags) \
TFC(FastCloneShallowObject, FastCloneShallowObject, 1) \
/* ES6 section 9.5.14 [[Construct]] ( argumentsList, newTarget) */ \ /* ES6 section 9.5.14 [[Construct]] ( argumentsList, newTarget) */ \
TFC(ConstructProxy, ConstructTrampoline, 1) \ TFC(ConstructProxy, ConstructTrampoline, 1) \
\ \
......
...@@ -113,19 +113,6 @@ Handle<Code> Builtins::NewFunctionContext(ScopeType scope_type) { ...@@ -113,19 +113,6 @@ Handle<Code> Builtins::NewFunctionContext(ScopeType scope_type) {
return Handle<Code>::null(); return Handle<Code>::null();
} }
Handle<Code> Builtins::NewCloneShallowArray(
AllocationSiteMode allocation_mode) {
switch (allocation_mode) {
case TRACK_ALLOCATION_SITE:
return builtin_handle(kFastCloneShallowArrayTrack);
case DONT_TRACK_ALLOCATION_SITE:
return builtin_handle(kFastCloneShallowArrayDontTrack);
default:
UNREACHABLE();
}
return Handle<Code>::null();
}
Handle<Code> Builtins::NonPrimitiveToPrimitive(ToPrimitiveHint hint) { Handle<Code> Builtins::NonPrimitiveToPrimitive(ToPrimitiveHint hint) {
switch (hint) { switch (hint) {
case ToPrimitiveHint::kDefault: case ToPrimitiveHint::kDefault:
......
...@@ -68,7 +68,6 @@ class Builtins { ...@@ -68,7 +68,6 @@ class Builtins {
InterpreterPushArgsMode mode); InterpreterPushArgsMode mode);
Handle<Code> InterpreterPushArgsThenConstruct(InterpreterPushArgsMode mode); Handle<Code> InterpreterPushArgsThenConstruct(InterpreterPushArgsMode mode);
Handle<Code> NewFunctionContext(ScopeType scope_type); Handle<Code> NewFunctionContext(ScopeType scope_type);
Handle<Code> NewCloneShallowArray(AllocationSiteMode allocation_mode);
Handle<Code> JSConstructStubGeneric(); Handle<Code> JSConstructStubGeneric();
// Used by BuiltinDeserializer. // Used by BuiltinDeserializer.
......
...@@ -202,13 +202,6 @@ Callable CodeFactory::HandleDebuggerStatement(Isolate* isolate) { ...@@ -202,13 +202,6 @@ Callable CodeFactory::HandleDebuggerStatement(Isolate* isolate) {
ContextOnlyDescriptor(isolate)); ContextOnlyDescriptor(isolate));
} }
// static
Callable CodeFactory::FastCloneShallowArray(
Isolate* isolate, AllocationSiteMode allocation_mode) {
return Callable(isolate->builtins()->NewCloneShallowArray(allocation_mode),
FastCloneShallowArrayDescriptor(isolate));
}
// static // static
Callable CodeFactory::FastNewFunctionContext(Isolate* isolate, Callable CodeFactory::FastNewFunctionContext(Isolate* isolate,
ScopeType scope_type) { ScopeType scope_type) {
......
...@@ -60,9 +60,6 @@ class V8_EXPORT_PRIVATE CodeFactory final { ...@@ -60,9 +60,6 @@ class V8_EXPORT_PRIVATE CodeFactory final {
static Callable StringCompare(Isolate* isolate, Token::Value token); static Callable StringCompare(Isolate* isolate, Token::Value token);
static Callable SubString(Isolate* isolate); static Callable SubString(Isolate* isolate);
static Callable FastCloneShallowArray(Isolate* isolate,
AllocationSiteMode allocation_mode);
static Callable FastNewFunctionContext(Isolate* isolate, static Callable FastNewFunctionContext(Isolate* isolate,
ScopeType scope_type); ScopeType scope_type);
......
...@@ -1480,11 +1480,11 @@ void BytecodeGraphBuilder::VisitCreateRestParameter() { ...@@ -1480,11 +1480,11 @@ void BytecodeGraphBuilder::VisitCreateRestParameter() {
void BytecodeGraphBuilder::VisitCreateRegExpLiteral() { void BytecodeGraphBuilder::VisitCreateRegExpLiteral() {
Handle<String> constant_pattern = Handle<String> constant_pattern =
Handle<String>::cast(bytecode_iterator().GetConstantForIndexOperand(0)); Handle<String>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
int literal_index = bytecode_iterator().GetIndexOperand(1); int const slot_id = bytecode_iterator().GetIndexOperand(1);
VectorSlotPair pair = CreateVectorSlotPair(slot_id);
int literal_flags = bytecode_iterator().GetFlagOperand(2); int literal_flags = bytecode_iterator().GetFlagOperand(2);
Node* literal = NewNode(javascript()->CreateLiteralRegExp( Node* literal = NewNode(
constant_pattern, literal_flags, literal_index), javascript()->CreateLiteralRegExp(constant_pattern, pair, literal_flags));
GetFunctionClosure());
environment()->BindAccumulator(literal, Environment::kAttachFrameState); environment()->BindAccumulator(literal, Environment::kAttachFrameState);
} }
...@@ -1492,7 +1492,8 @@ void BytecodeGraphBuilder::VisitCreateArrayLiteral() { ...@@ -1492,7 +1492,8 @@ void BytecodeGraphBuilder::VisitCreateArrayLiteral() {
Handle<ConstantElementsPair> constant_elements = Handle<ConstantElementsPair> constant_elements =
Handle<ConstantElementsPair>::cast( Handle<ConstantElementsPair>::cast(
bytecode_iterator().GetConstantForIndexOperand(0)); bytecode_iterator().GetConstantForIndexOperand(0));
int literal_index = bytecode_iterator().GetIndexOperand(1); int const slot_id = bytecode_iterator().GetIndexOperand(1);
VectorSlotPair pair = CreateVectorSlotPair(slot_id);
int bytecode_flags = bytecode_iterator().GetFlagOperand(2); int bytecode_flags = bytecode_iterator().GetFlagOperand(2);
int literal_flags = int literal_flags =
interpreter::CreateArrayLiteralFlags::FlagsBits::decode(bytecode_flags); interpreter::CreateArrayLiteralFlags::FlagsBits::decode(bytecode_flags);
...@@ -1504,17 +1505,15 @@ void BytecodeGraphBuilder::VisitCreateArrayLiteral() { ...@@ -1504,17 +1505,15 @@ void BytecodeGraphBuilder::VisitCreateArrayLiteral() {
// TODO(mstarzinger): Thread through number of elements. The below number is // TODO(mstarzinger): Thread through number of elements. The below number is
// only an estimate and does not match {ArrayLiteral::values::length}. // only an estimate and does not match {ArrayLiteral::values::length}.
int number_of_elements = constant_elements->constant_values()->length(); int number_of_elements = constant_elements->constant_values()->length();
Node* literal = NewNode( Node* literal = NewNode(javascript()->CreateLiteralArray(
javascript()->CreateLiteralArray(constant_elements, literal_flags, constant_elements, pair, literal_flags, number_of_elements));
literal_index, number_of_elements),
GetFunctionClosure());
environment()->BindAccumulator(literal, Environment::kAttachFrameState); environment()->BindAccumulator(literal, Environment::kAttachFrameState);
} }
void BytecodeGraphBuilder::VisitCreateEmptyArrayLiteral() { void BytecodeGraphBuilder::VisitCreateEmptyArrayLiteral() {
int literal_index = bytecode_iterator().GetIndexOperand(0); int const slot_id = bytecode_iterator().GetIndexOperand(0);
Node* literal = NewNode(javascript()->CreateEmptyLiteralArray(literal_index), VectorSlotPair pair = CreateVectorSlotPair(slot_id);
GetFunctionClosure()); Node* literal = NewNode(javascript()->CreateEmptyLiteralArray(pair));
environment()->BindAccumulator(literal); environment()->BindAccumulator(literal);
} }
...@@ -1522,17 +1521,16 @@ void BytecodeGraphBuilder::VisitCreateObjectLiteral() { ...@@ -1522,17 +1521,16 @@ void BytecodeGraphBuilder::VisitCreateObjectLiteral() {
Handle<BoilerplateDescription> constant_properties = Handle<BoilerplateDescription> constant_properties =
Handle<BoilerplateDescription>::cast( Handle<BoilerplateDescription>::cast(
bytecode_iterator().GetConstantForIndexOperand(0)); bytecode_iterator().GetConstantForIndexOperand(0));
int literal_index = bytecode_iterator().GetIndexOperand(1); int const slot_id = bytecode_iterator().GetIndexOperand(1);
VectorSlotPair pair = CreateVectorSlotPair(slot_id);
int bytecode_flags = bytecode_iterator().GetFlagOperand(2); int bytecode_flags = bytecode_iterator().GetFlagOperand(2);
int literal_flags = int literal_flags =
interpreter::CreateObjectLiteralFlags::FlagsBits::decode(bytecode_flags); interpreter::CreateObjectLiteralFlags::FlagsBits::decode(bytecode_flags);
// TODO(mstarzinger): Thread through number of properties. The below number is // TODO(mstarzinger): Thread through number of properties. The below number is
// only an estimate and does not match {ObjectLiteral::properties_count}. // only an estimate and does not match {ObjectLiteral::properties_count}.
int number_of_properties = constant_properties->size(); int number_of_properties = constant_properties->size();
Node* literal = NewNode( Node* literal = NewNode(javascript()->CreateLiteralObject(
javascript()->CreateLiteralObject(constant_properties, literal_flags, constant_properties, pair, literal_flags, number_of_properties));
literal_index, number_of_properties),
GetFunctionClosure());
environment()->BindRegister(bytecode_iterator().GetRegisterOperand(3), environment()->BindRegister(bytecode_iterator().GetRegisterOperand(3),
literal, Environment::kAttachFrameState); literal, Environment::kAttachFrameState);
} }
......
...@@ -854,12 +854,10 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralArrayOrObject(Node* node) { ...@@ -854,12 +854,10 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralArrayOrObject(Node* node) {
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node); Node* control = NodeProperties::GetControlInput(node);
Handle<FeedbackVector> feedback_vector; Handle<Object> feedback(p.feedback().vector()->Get(p.feedback().slot()),
if (GetSpecializationFeedbackVector(node).ToHandle(&feedback_vector)) { isolate());
FeedbackSlot slot(FeedbackVector::ToSlot(p.index())); if (feedback->IsAllocationSite()) {
Handle<Object> literal(feedback_vector->Get(slot), isolate()); Handle<AllocationSite> site = Handle<AllocationSite>::cast(feedback);
if (literal->IsAllocationSite()) {
Handle<AllocationSite> site = Handle<AllocationSite>::cast(literal);
Handle<JSObject> boilerplate(site->boilerplate(), isolate()); Handle<JSObject> boilerplate(site->boilerplate(), isolate());
int max_properties = kMaxFastLiteralProperties; int max_properties = kMaxFastLiteralProperties;
if (IsFastLiteral(boilerplate, kMaxFastLiteralDepth, &max_properties)) { if (IsFastLiteral(boilerplate, kMaxFastLiteralDepth, &max_properties)) {
...@@ -872,24 +870,20 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralArrayOrObject(Node* node) { ...@@ -872,24 +870,20 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralArrayOrObject(Node* node) {
return Replace(value); return Replace(value);
} }
} }
}
return NoChange(); return NoChange();
} }
Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralArray(Node* node) { Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralArray(Node* node) {
DCHECK_EQ(node->opcode(), IrOpcode::kJSCreateEmptyLiteralArray); DCHECK_EQ(IrOpcode::kJSCreateEmptyLiteralArray, node->opcode());
int literal_index = OpParameter<int>(node); FeedbackParameter const& p = FeedbackParameterOf(node->op());
Handle<FeedbackVector> feedback_vector; Handle<Object> feedback(p.feedback().vector()->Get(p.feedback().slot()),
if (GetSpecializationFeedbackVector(node).ToHandle(&feedback_vector)) { isolate());
FeedbackSlot slot(FeedbackVector::ToSlot(literal_index)); if (feedback->IsAllocationSite()) {
Handle<Object> raw_site(feedback_vector->Get(slot), isolate()); Handle<AllocationSite> site = Handle<AllocationSite>::cast(feedback);
if (raw_site->IsAllocationSite()) {
Handle<AllocationSite> site = Handle<AllocationSite>::cast(raw_site);
DCHECK(!site->PointsToLiteral()); DCHECK(!site->PointsToLiteral());
Node* length = jsgraph()->ZeroConstant(); Node* length = jsgraph()->ZeroConstant();
return ReduceNewArray(node, length, 0, site); return ReduceNewArray(node, length, 0, site);
} }
}
return NoChange(); return NoChange();
} }
...@@ -930,17 +924,14 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralRegExp(Node* node) { ...@@ -930,17 +924,14 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralRegExp(Node* node) {
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node); Node* control = NodeProperties::GetControlInput(node);
Handle<FeedbackVector> feedback_vector; Handle<Object> feedback(p.feedback().vector()->Get(p.feedback().slot()),
if (GetSpecializationFeedbackVector(node).ToHandle(&feedback_vector)) { isolate());
FeedbackSlot slot(FeedbackVector::ToSlot(p.index())); if (feedback->IsJSRegExp()) {
Handle<Object> maybe_boilerplate(feedback_vector->Get(slot), isolate()); Handle<JSRegExp> boilerplate = Handle<JSRegExp>::cast(feedback);
if (maybe_boilerplate->IsJSRegExp()) { Node* value = effect = AllocateLiteralRegExp(effect, control, boilerplate);
Node* value = effect = AllocateLiteralRegExp(
effect, control, Handle<JSRegExp>::cast(maybe_boilerplate));
ReplaceWithValue(node, value, effect, control); ReplaceWithValue(node, value, effect, control);
return Replace(value); return Replace(value);
} }
}
return NoChange(); return NoChange();
} }
...@@ -1505,30 +1496,6 @@ Node* JSCreateLowering::AllocateLiteralRegExp(Node* effect, Node* control, ...@@ -1505,30 +1496,6 @@ Node* JSCreateLowering::AllocateLiteralRegExp(Node* effect, Node* control,
return builder.Finish(); return builder.Finish();
} }
MaybeHandle<FeedbackVector> JSCreateLowering::GetSpecializationFeedbackVector(
Node* node) {
Node* const closure = NodeProperties::GetValueInput(node, 0);
switch (closure->opcode()) {
case IrOpcode::kHeapConstant: {
Handle<HeapObject> object = OpParameter<Handle<HeapObject>>(closure);
return handle(Handle<JSFunction>::cast(object)->feedback_vector());
}
case IrOpcode::kParameter: {
int const index = ParameterIndexOf(closure->op());
// The closure is always the last parameter to a JavaScript function, and
// {Parameter} indices start at -1, so value outputs of {Start} look like
// this: closure, receiver, param0, ..., paramN, context.
if (index == -1) {
return feedback_vector_;
}
break;
}
default:
break;
}
return MaybeHandle<FeedbackVector>();
}
Factory* JSCreateLowering::factory() const { return isolate()->factory(); } Factory* JSCreateLowering::factory() const { return isolate()->factory(); }
Graph* JSCreateLowering::graph() const { return jsgraph()->graph(); } Graph* JSCreateLowering::graph() const { return jsgraph()->graph(); }
......
...@@ -34,12 +34,10 @@ class V8_EXPORT_PRIVATE JSCreateLowering final ...@@ -34,12 +34,10 @@ class V8_EXPORT_PRIVATE JSCreateLowering final
public: public:
JSCreateLowering(Editor* editor, CompilationDependencies* dependencies, JSCreateLowering(Editor* editor, CompilationDependencies* dependencies,
JSGraph* jsgraph, JSGraph* jsgraph,
MaybeHandle<FeedbackVector> feedback_vector,
Handle<Context> native_context, Zone* zone) Handle<Context> native_context, Zone* zone)
: AdvancedReducer(editor), : AdvancedReducer(editor),
dependencies_(dependencies), dependencies_(dependencies),
jsgraph_(jsgraph), jsgraph_(jsgraph),
feedback_vector_(feedback_vector),
native_context_(native_context), native_context_(native_context),
zone_(zone) {} zone_(zone) {}
~JSCreateLowering() final {} ~JSCreateLowering() final {}
...@@ -99,9 +97,6 @@ class V8_EXPORT_PRIVATE JSCreateLowering final ...@@ -99,9 +97,6 @@ class V8_EXPORT_PRIVATE JSCreateLowering final
Reduction ReduceNewArrayToStubCall(Node* node, Handle<AllocationSite> site); Reduction ReduceNewArrayToStubCall(Node* node, Handle<AllocationSite> site);
// Infers the FeedbackVector to use for a given {node}.
MaybeHandle<FeedbackVector> GetSpecializationFeedbackVector(Node* node);
Factory* factory() const; Factory* factory() const;
Graph* graph() const; Graph* graph() const;
JSGraph* jsgraph() const { return jsgraph_; } JSGraph* jsgraph() const { return jsgraph_; }
...@@ -114,7 +109,6 @@ class V8_EXPORT_PRIVATE JSCreateLowering final ...@@ -114,7 +109,6 @@ class V8_EXPORT_PRIVATE JSCreateLowering final
CompilationDependencies* const dependencies_; CompilationDependencies* const dependencies_;
JSGraph* const jsgraph_; JSGraph* const jsgraph_;
MaybeHandle<FeedbackVector> const feedback_vector_;
Handle<Context> const native_context_; Handle<Context> const native_context_;
Zone* const zone_; Zone* const zone_;
}; };
......
...@@ -461,15 +461,16 @@ void JSGenericLowering::LowerJSCreateKeyValueArray(Node* node) { ...@@ -461,15 +461,16 @@ void JSGenericLowering::LowerJSCreateKeyValueArray(Node* node) {
void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) { void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) {
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op()); CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
CallDescriptor::Flags flags = FrameStateFlagForCall(node); CallDescriptor::Flags flags = FrameStateFlagForCall(node);
node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.index())); node->InsertInput(zone(), 0, jsgraph()->HeapConstant(p.feedback().vector()));
node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.feedback().index()));
node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant())); node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant()));
// Use the FastCloneShallowArray builtin only for shallow boilerplates without // Use the CreateShallowArrayLiteratlr builtin only for shallow boilerplates
// properties up to the number of elements that the stubs can handle. // without properties up to the number of elements that the stubs can handle.
if ((p.flags() & AggregateLiteral::kIsShallow) != 0 && if ((p.flags() & AggregateLiteral::kIsShallow) != 0 &&
p.length() < ConstructorBuiltins::kMaximumClonedShallowArrayElements) { p.length() < ConstructorBuiltins::kMaximumClonedShallowArrayElements) {
Callable callable = CodeFactory::FastCloneShallowArray( Callable callable =
isolate(), DONT_TRACK_ALLOCATION_SITE); Builtins::CallableFor(isolate(), Builtins::kCreateShallowArrayLiteral);
ReplaceWithStubCall(node, callable, flags); ReplaceWithStubCall(node, callable, flags);
} else { } else {
node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags())); node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags()));
...@@ -479,8 +480,10 @@ void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) { ...@@ -479,8 +480,10 @@ void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) {
void JSGenericLowering::LowerJSCreateEmptyLiteralArray(Node* node) { void JSGenericLowering::LowerJSCreateEmptyLiteralArray(Node* node) {
CallDescriptor::Flags flags = FrameStateFlagForCall(node); CallDescriptor::Flags flags = FrameStateFlagForCall(node);
int literal_index = OpParameter<int>(node->op()); FeedbackParameter const& p = FeedbackParameterOf(node->op());
node->InsertInput(zone(), 1, jsgraph()->SmiConstant(literal_index)); node->InsertInput(zone(), 0, jsgraph()->HeapConstant(p.feedback().vector()));
node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.feedback().index()));
node->RemoveInput(4); // control
Callable callable = Callable callable =
Builtins::CallableFor(isolate(), Builtins::kCreateEmptyArrayLiteral); Builtins::CallableFor(isolate(), Builtins::kCreateEmptyArrayLiteral);
ReplaceWithStubCall(node, callable, flags); ReplaceWithStubCall(node, callable, flags);
...@@ -489,17 +492,18 @@ void JSGenericLowering::LowerJSCreateEmptyLiteralArray(Node* node) { ...@@ -489,17 +492,18 @@ void JSGenericLowering::LowerJSCreateEmptyLiteralArray(Node* node) {
void JSGenericLowering::LowerJSCreateLiteralObject(Node* node) { void JSGenericLowering::LowerJSCreateLiteralObject(Node* node) {
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op()); CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
CallDescriptor::Flags flags = FrameStateFlagForCall(node); CallDescriptor::Flags flags = FrameStateFlagForCall(node);
node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.index())); node->InsertInput(zone(), 0, jsgraph()->HeapConstant(p.feedback().vector()));
node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.feedback().index()));
node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant())); node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant()));
node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags())); node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags()));
// Use the FastCloneShallowObject builtin only for shallow boilerplates // Use the CreateShallowObjectLiteratal builtin only for shallow boilerplates
// without elements up to the number of properties that the stubs can handle. // without elements up to the number of properties that the stubs can handle.
if ((p.flags() & AggregateLiteral::kIsShallow) != 0 && if ((p.flags() & AggregateLiteral::kIsShallow) != 0 &&
p.length() <= p.length() <=
ConstructorBuiltins::kMaximumClonedShallowObjectProperties) { ConstructorBuiltins::kMaximumClonedShallowObjectProperties) {
Callable callable = Callable callable =
Builtins::CallableFor(isolate(), Builtins::kFastCloneShallowObject); Builtins::CallableFor(isolate(), Builtins::kCreateShallowObjectLiteral);
ReplaceWithStubCall(node, callable, flags); ReplaceWithStubCall(node, callable, flags);
} else { } else {
ReplaceWithRuntimeCall(node, Runtime::kCreateObjectLiteral); ReplaceWithRuntimeCall(node, Runtime::kCreateObjectLiteral);
...@@ -507,23 +511,18 @@ void JSGenericLowering::LowerJSCreateLiteralObject(Node* node) { ...@@ -507,23 +511,18 @@ void JSGenericLowering::LowerJSCreateLiteralObject(Node* node) {
} }
void JSGenericLowering::LowerJSCreateEmptyLiteralObject(Node* node) { void JSGenericLowering::LowerJSCreateEmptyLiteralObject(Node* node) {
CallDescriptor::Flags flags = FrameStateFlagForCall(node); UNREACHABLE(); // Eliminated in typed lowering.
Callable callable =
Builtins::CallableFor(isolate(), Builtins::kCreateEmptyObjectLiteral);
ReplaceWithStubCall(node, callable, flags);
} }
void JSGenericLowering::LowerJSCreateLiteralRegExp(Node* node) { void JSGenericLowering::LowerJSCreateLiteralRegExp(Node* node) {
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op()); CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
CallDescriptor::Flags flags = FrameStateFlagForCall(node); CallDescriptor::Flags flags = FrameStateFlagForCall(node);
Callable callable = Callable callable =
Builtins::CallableFor(isolate(), Builtins::kFastCloneRegExp); Builtins::CallableFor(isolate(), Builtins::kCreateRegExpLiteral);
Node* literal_index = jsgraph()->SmiConstant(p.index()); node->InsertInput(zone(), 0, jsgraph()->HeapConstant(p.feedback().vector()));
Node* literal_flags = jsgraph()->SmiConstant(p.flags()); node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.feedback().index()));
Node* pattern = jsgraph()->HeapConstant(p.constant()); node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant()));
node->InsertInput(graph()->zone(), 1, literal_index); node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags()));
node->InsertInput(graph()->zone(), 2, pattern);
node->InsertInput(graph()->zone(), 3, literal_flags);
ReplaceWithStubCall(node, callable, flags); ReplaceWithStubCall(node, callable, flags);
} }
......
...@@ -290,7 +290,8 @@ std::ostream& operator<<(std::ostream& os, FeedbackParameter const& p) { ...@@ -290,7 +290,8 @@ std::ostream& operator<<(std::ostream& os, FeedbackParameter const& p) {
} }
FeedbackParameter const& FeedbackParameterOf(const Operator* op) { FeedbackParameter const& FeedbackParameterOf(const Operator* op) {
DCHECK_EQ(IrOpcode::kJSStoreDataPropertyInLiteral, op->opcode()); DCHECK(op->opcode() == IrOpcode::kJSCreateEmptyLiteralArray ||
op->opcode() == IrOpcode::kJSStoreDataPropertyInLiteral);
return OpParameter<FeedbackParameter>(op); return OpParameter<FeedbackParameter>(op);
} }
...@@ -484,8 +485,8 @@ const CreateClosureParameters& CreateClosureParametersOf(const Operator* op) { ...@@ -484,8 +485,8 @@ const CreateClosureParameters& CreateClosureParametersOf(const Operator* op) {
bool operator==(CreateLiteralParameters const& lhs, bool operator==(CreateLiteralParameters const& lhs,
CreateLiteralParameters const& rhs) { CreateLiteralParameters const& rhs) {
return lhs.constant().location() == rhs.constant().location() && return lhs.constant().location() == rhs.constant().location() &&
lhs.length() == rhs.length() && lhs.flags() == rhs.flags() && lhs.feedback() == rhs.feedback() && lhs.length() == rhs.length() &&
lhs.index() == rhs.index(); lhs.flags() == rhs.flags();
} }
...@@ -496,14 +497,13 @@ bool operator!=(CreateLiteralParameters const& lhs, ...@@ -496,14 +497,13 @@ bool operator!=(CreateLiteralParameters const& lhs,
size_t hash_value(CreateLiteralParameters const& p) { size_t hash_value(CreateLiteralParameters const& p) {
return base::hash_combine(p.constant().location(), p.length(), p.flags(), return base::hash_combine(p.constant().location(), p.feedback(), p.length(),
p.index()); p.flags());
} }
std::ostream& operator<<(std::ostream& os, CreateLiteralParameters const& p) { std::ostream& operator<<(std::ostream& os, CreateLiteralParameters const& p) {
return os << Brief(*p.constant()) << ", " << p.length() << ", " << p.flags() return os << Brief(*p.constant()) << ", " << p.length() << ", " << p.flags();
<< ", " << p.index();
} }
...@@ -1049,35 +1049,40 @@ const Operator* JSOperatorBuilder::CreateClosure( ...@@ -1049,35 +1049,40 @@ const Operator* JSOperatorBuilder::CreateClosure(
} }
const Operator* JSOperatorBuilder::CreateLiteralArray( const Operator* JSOperatorBuilder::CreateLiteralArray(
Handle<ConstantElementsPair> constant_elements, int literal_flags, Handle<ConstantElementsPair> constant_elements,
int literal_index, int number_of_elements) { VectorSlotPair const& feedback, int literal_flags, int number_of_elements) {
CreateLiteralParameters parameters(constant_elements, number_of_elements, CreateLiteralParameters parameters(constant_elements, feedback,
literal_flags, literal_index); number_of_elements, literal_flags);
return new (zone()) Operator1<CreateLiteralParameters>( // -- return new (zone()) Operator1<CreateLiteralParameters>( // --
IrOpcode::kJSCreateLiteralArray, Operator::kNoProperties, // opcode IrOpcode::kJSCreateLiteralArray, // opcode
Operator::kNoProperties, // properties
"JSCreateLiteralArray", // name "JSCreateLiteralArray", // name
1, 1, 1, 1, 1, 2, // counts 0, 1, 1, 1, 1, 2, // counts
parameters); // parameter parameters); // parameter
} }
const Operator* JSOperatorBuilder::CreateEmptyLiteralArray(int literal_index) { const Operator* JSOperatorBuilder::CreateEmptyLiteralArray(
return new (zone()) Operator1<int>( // -- VectorSlotPair const& feedback) {
FeedbackParameter parameters(feedback);
return new (zone()) Operator1<FeedbackParameter>( // --
IrOpcode::kJSCreateEmptyLiteralArray, // opcode IrOpcode::kJSCreateEmptyLiteralArray, // opcode
Operator::kNoProperties, // properties Operator::kEliminatable, // properties
"JSCreateEmptyLiteralArray", // name "JSCreateEmptyLiteralArray", // name
1, 1, 1, 1, 1, 2, // counts 0, 1, 1, 1, 1, 0, // counts
literal_index); // parameter parameters); // parameter
} }
const Operator* JSOperatorBuilder::CreateLiteralObject( const Operator* JSOperatorBuilder::CreateLiteralObject(
Handle<BoilerplateDescription> constant_properties, int literal_flags, Handle<BoilerplateDescription> constant_properties,
int literal_index, int number_of_properties) { VectorSlotPair const& feedback, int literal_flags,
CreateLiteralParameters parameters(constant_properties, number_of_properties, int number_of_properties) {
literal_flags, literal_index); CreateLiteralParameters parameters(constant_properties, feedback,
number_of_properties, literal_flags);
return new (zone()) Operator1<CreateLiteralParameters>( // -- return new (zone()) Operator1<CreateLiteralParameters>( // --
IrOpcode::kJSCreateLiteralObject, Operator::kNoProperties, // opcode IrOpcode::kJSCreateLiteralObject, // opcode
Operator::kNoProperties, // properties
"JSCreateLiteralObject", // name "JSCreateLiteralObject", // name
1, 1, 1, 1, 1, 2, // counts 0, 1, 1, 1, 1, 2, // counts
parameters); // parameter parameters); // parameter
} }
...@@ -1090,13 +1095,15 @@ const Operator* JSOperatorBuilder::CreateEmptyLiteralObject() { ...@@ -1090,13 +1095,15 @@ const Operator* JSOperatorBuilder::CreateEmptyLiteralObject() {
} }
const Operator* JSOperatorBuilder::CreateLiteralRegExp( const Operator* JSOperatorBuilder::CreateLiteralRegExp(
Handle<String> constant_pattern, int literal_flags, int literal_index) { Handle<String> constant_pattern, VectorSlotPair const& feedback,
CreateLiteralParameters parameters(constant_pattern, -1, literal_flags, int literal_flags) {
literal_index); CreateLiteralParameters parameters(constant_pattern, feedback, -1,
literal_flags);
return new (zone()) Operator1<CreateLiteralParameters>( // -- return new (zone()) Operator1<CreateLiteralParameters>( // --
IrOpcode::kJSCreateLiteralRegExp, Operator::kNoProperties, // opcode IrOpcode::kJSCreateLiteralRegExp, // opcode
Operator::kNoProperties, // properties
"JSCreateLiteralRegExp", // name "JSCreateLiteralRegExp", // name
1, 1, 1, 1, 1, 2, // counts 0, 1, 1, 1, 1, 2, // counts
parameters); // parameter parameters); // parameter
} }
......
...@@ -366,8 +366,8 @@ std::ostream& operator<<(std::ostream&, StoreNamedOwnParameters const&); ...@@ -366,8 +366,8 @@ std::ostream& operator<<(std::ostream&, StoreNamedOwnParameters const&);
const StoreNamedOwnParameters& StoreNamedOwnParametersOf(const Operator* op); const StoreNamedOwnParameters& StoreNamedOwnParametersOf(const Operator* op);
// Defines the feedback, i.e., vector and index, for storing a data property in // Defines the feedback, i.e., vector and index, for storing a data property in
// an object literal. This is // an object literal. This is used as a parameter by JSCreateEmptyLiteralArray
// used as a parameter by the JSStoreDataPropertyInLiteral operator. // and JSStoreDataPropertyInLiteral operators.
class FeedbackParameter final { class FeedbackParameter final {
public: public:
explicit FeedbackParameter(VectorSlotPair const& feedback) explicit FeedbackParameter(VectorSlotPair const& feedback)
...@@ -561,20 +561,23 @@ const CreateClosureParameters& CreateClosureParametersOf(const Operator* op); ...@@ -561,20 +561,23 @@ const CreateClosureParameters& CreateClosureParametersOf(const Operator* op);
// JSCreateLiteralRegExp operators. // JSCreateLiteralRegExp operators.
class CreateLiteralParameters final { class CreateLiteralParameters final {
public: public:
CreateLiteralParameters(Handle<HeapObject> constant, int length, int flags, CreateLiteralParameters(Handle<HeapObject> constant,
int index) VectorSlotPair const& feedback, int length, int flags)
: constant_(constant), length_(length), flags_(flags), index_(index) {} : constant_(constant),
feedback_(feedback),
length_(length),
flags_(flags) {}
Handle<HeapObject> constant() const { return constant_; } Handle<HeapObject> constant() const { return constant_; }
VectorSlotPair const& feedback() const { return feedback_; }
int length() const { return length_; } int length() const { return length_; }
int flags() const { return flags_; } int flags() const { return flags_; }
int index() const { return index_; }
private: private:
Handle<HeapObject> const constant_; Handle<HeapObject> const constant_;
VectorSlotPair const feedback_;
int const length_; int const length_;
int const flags_; int const flags_;
int const index_;
}; };
bool operator==(CreateLiteralParameters const&, CreateLiteralParameters const&); bool operator==(CreateLiteralParameters const&, CreateLiteralParameters const&);
...@@ -647,16 +650,18 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final ...@@ -647,16 +650,18 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final
const Operator* CreateIterResultObject(); const Operator* CreateIterResultObject();
const Operator* CreateKeyValueArray(); const Operator* CreateKeyValueArray();
const Operator* CreateLiteralArray(Handle<ConstantElementsPair> constant, const Operator* CreateLiteralArray(Handle<ConstantElementsPair> constant,
int literal_flags, int literal_index, VectorSlotPair const& feedback,
int number_of_elements); int literal_flags, int number_of_elements);
const Operator* CreateEmptyLiteralArray(int literal_index); const Operator* CreateEmptyLiteralArray(VectorSlotPair const& feedback);
const Operator* CreateEmptyLiteralObject(); const Operator* CreateEmptyLiteralObject();
const Operator* CreateLiteralObject(Handle<BoilerplateDescription> constant, const Operator* CreateLiteralObject(Handle<BoilerplateDescription> constant,
int literal_flags, int literal_index, VectorSlotPair const& feedback,
int literal_flags,
int number_of_properties); int number_of_properties);
const Operator* CreateLiteralRegExp(Handle<String> constant_pattern, const Operator* CreateLiteralRegExp(Handle<String> constant_pattern,
int literal_flags, int literal_index); VectorSlotPair const& feedback,
int literal_flags);
const Operator* CallForwardVarargs(size_t arity, uint32_t start_index); const Operator* CallForwardVarargs(size_t arity, uint32_t start_index);
const Operator* Call( const Operator* Call(
......
...@@ -1028,11 +1028,9 @@ struct TypedLoweringPhase { ...@@ -1028,11 +1028,9 @@ struct TypedLoweringPhase {
JSBuiltinReducer builtin_reducer( JSBuiltinReducer builtin_reducer(
&graph_reducer, data->jsgraph(), &graph_reducer, data->jsgraph(),
data->info()->dependencies(), data->native_context()); data->info()->dependencies(), data->native_context());
Handle<FeedbackVector> feedback_vector(
data->info()->closure()->feedback_vector());
JSCreateLowering create_lowering( JSCreateLowering create_lowering(
&graph_reducer, data->info()->dependencies(), data->jsgraph(), &graph_reducer, data->info()->dependencies(), data->jsgraph(),
feedback_vector, data->native_context(), temp_zone); data->native_context(), temp_zone);
JSTypedLowering typed_lowering(&graph_reducer, data->jsgraph(), temp_zone); JSTypedLowering typed_lowering(&graph_reducer, data->jsgraph(), temp_zone);
TypedOptimization typed_optimization( TypedOptimization typed_optimization(
&graph_reducer, data->info()->dependencies(), data->jsgraph()); &graph_reducer, data->info()->dependencies(), data->jsgraph());
......
...@@ -90,27 +90,6 @@ void TypeofDescriptor::InitializePlatformSpecific( ...@@ -90,27 +90,6 @@ void TypeofDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers, NULL); data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
} }
void FastCloneRegExpDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {edi, eax, ecx, edx};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {eax, ebx, ecx};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {eax, ebx, ecx, edx};
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
}
void CallFunctionDescriptor::InitializePlatformSpecific( void CallFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = {edi}; Register registers[] = {edi};
......
...@@ -400,26 +400,6 @@ void NewArgumentsElementsDescriptor::InitializePlatformSpecific( ...@@ -400,26 +400,6 @@ void NewArgumentsElementsDescriptor::InitializePlatformSpecific(
DefaultInitializePlatformSpecific(data, 3); DefaultInitializePlatformSpecific(data, 3);
} }
void FastCloneRegExpDescriptor::InitializePlatformIndependent(
CallInterfaceDescriptorData* data) {
// kClosure, kLiteralIndex, kPattern, kFlags
MachineType machine_types[] = {
MachineType::AnyTagged(), MachineType::TaggedSigned(),
MachineType::AnyTagged(), MachineType::AnyTagged()};
data->InitializePlatformIndependent(arraysize(machine_types), 0,
machine_types);
}
void FastCloneShallowArrayDescriptor::InitializePlatformIndependent(
CallInterfaceDescriptorData* data) {
// kClosure, kLiteralIndex, kConstantElements
MachineType machine_types[] = {MachineType::AnyTagged(),
MachineType::TaggedSigned(),
MachineType::AnyTagged()};
data->InitializePlatformIndependent(arraysize(machine_types), 0,
machine_types);
}
void CallTrampolineDescriptor::InitializePlatformIndependent( void CallTrampolineDescriptor::InitializePlatformIndependent(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
// kFunction, kActualArgumentsCount // kFunction, kActualArgumentsCount
......
...@@ -37,9 +37,6 @@ class PlatformInterfaceDescriptor; ...@@ -37,9 +37,6 @@ class PlatformInterfaceDescriptor;
V(TypeConversion) \ V(TypeConversion) \
V(TypeConversionStackParameter) \ V(TypeConversionStackParameter) \
V(Typeof) \ V(Typeof) \
V(FastCloneRegExp) \
V(FastCloneShallowArray) \
V(FastCloneShallowObject) \
V(CallFunction) \ V(CallFunction) \
V(CallVarargs) \ V(CallVarargs) \
V(CallForwardVarargs) \ V(CallForwardVarargs) \
...@@ -560,29 +557,6 @@ class TypeofDescriptor : public CallInterfaceDescriptor { ...@@ -560,29 +557,6 @@ class TypeofDescriptor : public CallInterfaceDescriptor {
DECLARE_DESCRIPTOR(TypeofDescriptor, CallInterfaceDescriptor) DECLARE_DESCRIPTOR(TypeofDescriptor, CallInterfaceDescriptor)
}; };
class FastCloneRegExpDescriptor : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kClosure, kLiteralIndex, kPattern, kFlags)
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(FastCloneRegExpDescriptor,
CallInterfaceDescriptor)
};
class FastCloneShallowArrayDescriptor : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kClosure, kLiteralIndex, kConstantElements)
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(FastCloneShallowArrayDescriptor,
CallInterfaceDescriptor)
};
class FastCloneShallowObjectDescriptor : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kClosure, kLiteralIndex, kBoilerplateDescription, kFlags)
DECLARE_DESCRIPTOR(FastCloneShallowObjectDescriptor, CallInterfaceDescriptor)
};
class CallTrampolineDescriptor : public CallInterfaceDescriptor { class CallTrampolineDescriptor : public CallInterfaceDescriptor {
public: public:
DEFINE_PARAMETERS(kFunction, kActualArgumentsCount) DEFINE_PARAMETERS(kFunction, kActualArgumentsCount)
......
...@@ -1933,7 +1933,7 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -1933,7 +1933,7 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
object_literals_.push_back(std::make_pair(expr, entry)); object_literals_.push_back(std::make_pair(expr, entry));
} }
// TODO(cbruni): Directly generate runtime call for literals we cannot // TODO(cbruni): Directly generate runtime call for literals we cannot
// optimize once the FastCloneShallowObject stub is in sync with the TF // optimize once the CreateShallowObjectLiteral stub is in sync with the TF
// optimizations. // optimizations.
builder()->CreateObjectLiteral(entry, literal_index, flags, literal); builder()->CreateObjectLiteral(entry, literal_index, flags, literal);
......
...@@ -2643,15 +2643,15 @@ IGNITION_HANDLER(SwitchOnSmiNoFeedback, InterpreterAssembler) { ...@@ -2643,15 +2643,15 @@ IGNITION_HANDLER(SwitchOnSmiNoFeedback, InterpreterAssembler) {
// Creates a regular expression literal for literal index <literal_idx> with // Creates a regular expression literal for literal index <literal_idx> with
// <flags> and the pattern in <pattern_idx>. // <flags> and the pattern in <pattern_idx>.
IGNITION_HANDLER(CreateRegExpLiteral, InterpreterAssembler) { IGNITION_HANDLER(CreateRegExpLiteral, InterpreterAssembler) {
Node* index = BytecodeOperandIdx(0); Node* pattern_index = BytecodeOperandIdx(0);
Node* pattern = LoadConstantPoolEntry(index); Node* pattern = LoadConstantPoolEntry(pattern_index);
Node* literal_index = BytecodeOperandIdxSmi(1); Node* feedback_vector = LoadFeedbackVector();
Node* slot_id = BytecodeOperandIdx(1);
Node* flags = SmiFromWord32(BytecodeOperandFlag(2)); Node* flags = SmiFromWord32(BytecodeOperandFlag(2));
Node* closure = LoadRegister(Register::function_closure());
Node* context = GetContext(); Node* context = GetContext();
ConstructorBuiltinsAssembler constructor_assembler(state()); ConstructorBuiltinsAssembler constructor_assembler(state());
Node* result = constructor_assembler.EmitFastCloneRegExp( Node* result = constructor_assembler.EmitCreateRegExpLiteral(
closure, literal_index, pattern, flags, context); feedback_vector, slot_id, pattern, flags, context);
SetAccumulator(result); SetAccumulator(result);
Dispatch(); Dispatch();
} }
...@@ -2661,8 +2661,8 @@ IGNITION_HANDLER(CreateRegExpLiteral, InterpreterAssembler) { ...@@ -2661,8 +2661,8 @@ IGNITION_HANDLER(CreateRegExpLiteral, InterpreterAssembler) {
// Creates an array literal for literal index <literal_idx> with // Creates an array literal for literal index <literal_idx> with
// CreateArrayLiteral flags <flags> and constant elements in <element_idx>. // CreateArrayLiteral flags <flags> and constant elements in <element_idx>.
IGNITION_HANDLER(CreateArrayLiteral, InterpreterAssembler) { IGNITION_HANDLER(CreateArrayLiteral, InterpreterAssembler) {
Node* literal_index = BytecodeOperandIdxSmi(1); Node* feedback_vector = LoadFeedbackVector();
Node* closure = LoadRegister(Register::function_closure()); Node* slot_id = BytecodeOperandIdx(1);
Node* context = GetContext(); Node* context = GetContext();
Node* bytecode_flags = BytecodeOperandFlag(2); Node* bytecode_flags = BytecodeOperandFlag(2);
...@@ -2674,8 +2674,9 @@ IGNITION_HANDLER(CreateArrayLiteral, InterpreterAssembler) { ...@@ -2674,8 +2674,9 @@ IGNITION_HANDLER(CreateArrayLiteral, InterpreterAssembler) {
BIND(&fast_shallow_clone); BIND(&fast_shallow_clone);
{ {
ConstructorBuiltinsAssembler constructor_assembler(state()); ConstructorBuiltinsAssembler constructor_assembler(state());
Node* result = constructor_assembler.EmitFastCloneShallowArray( Node* result = constructor_assembler.EmitCreateShallowArrayLiteral(
closure, literal_index, context, &call_runtime, TRACK_ALLOCATION_SITE); feedback_vector, slot_id, context, &call_runtime,
TRACK_ALLOCATION_SITE);
SetAccumulator(result); SetAccumulator(result);
Dispatch(); Dispatch();
} }
...@@ -2687,8 +2688,9 @@ IGNITION_HANDLER(CreateArrayLiteral, InterpreterAssembler) { ...@@ -2687,8 +2688,9 @@ IGNITION_HANDLER(CreateArrayLiteral, InterpreterAssembler) {
Node* flags = SmiTag(flags_raw); Node* flags = SmiTag(flags_raw);
Node* index = BytecodeOperandIdx(0); Node* index = BytecodeOperandIdx(0);
Node* constant_elements = LoadConstantPoolEntry(index); Node* constant_elements = LoadConstantPoolEntry(index);
Node* result = CallRuntime(Runtime::kCreateArrayLiteral, context, closure, Node* result =
literal_index, constant_elements, flags); CallRuntime(Runtime::kCreateArrayLiteral, context, feedback_vector,
SmiTag(slot_id), constant_elements, flags);
SetAccumulator(result); SetAccumulator(result);
Dispatch(); Dispatch();
} }
...@@ -2698,12 +2700,12 @@ IGNITION_HANDLER(CreateArrayLiteral, InterpreterAssembler) { ...@@ -2698,12 +2700,12 @@ IGNITION_HANDLER(CreateArrayLiteral, InterpreterAssembler) {
// //
// Creates an empty JSArray literal for literal index <literal_idx>. // Creates an empty JSArray literal for literal index <literal_idx>.
IGNITION_HANDLER(CreateEmptyArrayLiteral, InterpreterAssembler) { IGNITION_HANDLER(CreateEmptyArrayLiteral, InterpreterAssembler) {
Node* literal_index = BytecodeOperandIdxSmi(0); Node* feedback_vector = LoadFeedbackVector();
Node* closure = LoadRegister(Register::function_closure()); Node* slot_id = BytecodeOperandIdx(0);
Node* context = GetContext(); Node* context = GetContext();
ConstructorBuiltinsAssembler constructor_assembler(state()); ConstructorBuiltinsAssembler constructor_assembler(state());
Node* result = constructor_assembler.EmitCreateEmptyArrayLiteral( Node* result = constructor_assembler.EmitCreateEmptyArrayLiteral(
closure, literal_index, context); feedback_vector, slot_id, context);
SetAccumulator(result); SetAccumulator(result);
Dispatch(); Dispatch();
} }
...@@ -2713,9 +2715,9 @@ IGNITION_HANDLER(CreateEmptyArrayLiteral, InterpreterAssembler) { ...@@ -2713,9 +2715,9 @@ IGNITION_HANDLER(CreateEmptyArrayLiteral, InterpreterAssembler) {
// Creates an object literal for literal index <literal_idx> with // Creates an object literal for literal index <literal_idx> with
// CreateObjectLiteralFlags <flags> and constant elements in <element_idx>. // CreateObjectLiteralFlags <flags> and constant elements in <element_idx>.
IGNITION_HANDLER(CreateObjectLiteral, InterpreterAssembler) { IGNITION_HANDLER(CreateObjectLiteral, InterpreterAssembler) {
Node* literal_index = BytecodeOperandIdxSmi(1); Node* feedback_vector = LoadFeedbackVector();
Node* slot_id = BytecodeOperandIdx(1);
Node* bytecode_flags = BytecodeOperandFlag(2); Node* bytecode_flags = BytecodeOperandFlag(2);
Node* closure = LoadRegister(Register::function_closure());
// Check if we can do a fast clone or have to call the runtime. // Check if we can do a fast clone or have to call the runtime.
Label if_fast_clone(this), if_not_fast_clone(this, Label::kDeferred); Label if_fast_clone(this), if_not_fast_clone(this, Label::kDeferred);
...@@ -2725,10 +2727,10 @@ IGNITION_HANDLER(CreateObjectLiteral, InterpreterAssembler) { ...@@ -2725,10 +2727,10 @@ IGNITION_HANDLER(CreateObjectLiteral, InterpreterAssembler) {
BIND(&if_fast_clone); BIND(&if_fast_clone);
{ {
// If we can do a fast clone do the fast-path in FastCloneShallowObjectStub. // If we can do a fast clone do the fast-path in CreateShallowObjectLiteral.
ConstructorBuiltinsAssembler constructor_assembler(state()); ConstructorBuiltinsAssembler constructor_assembler(state());
Node* result = constructor_assembler.EmitFastCloneShallowObject( Node* result = constructor_assembler.EmitCreateShallowObjectLiteral(
&if_not_fast_clone, closure, literal_index); feedback_vector, slot_id, &if_not_fast_clone);
StoreRegister(result, BytecodeOperandReg(3)); StoreRegister(result, BytecodeOperandReg(3));
Dispatch(); Dispatch();
} }
...@@ -2744,8 +2746,9 @@ IGNITION_HANDLER(CreateObjectLiteral, InterpreterAssembler) { ...@@ -2744,8 +2746,9 @@ IGNITION_HANDLER(CreateObjectLiteral, InterpreterAssembler) {
bytecode_flags); bytecode_flags);
Node* flags = SmiTag(flags_raw); Node* flags = SmiTag(flags_raw);
Node* result = CallRuntime(Runtime::kCreateObjectLiteral, context, closure, Node* result =
literal_index, boilerplate_description, flags); CallRuntime(Runtime::kCreateObjectLiteral, context, feedback_vector,
SmiTag(slot_id), boilerplate_description, flags);
StoreRegister(result, BytecodeOperandReg(3)); StoreRegister(result, BytecodeOperandReg(3));
// TODO(klaasb) build a single dispatch once the call is inlined // TODO(klaasb) build a single dispatch once the call is inlined
Dispatch(); Dispatch();
......
...@@ -88,27 +88,6 @@ void TypeofDescriptor::InitializePlatformSpecific( ...@@ -88,27 +88,6 @@ void TypeofDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers, NULL); data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
} }
void FastCloneRegExpDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {a3, a2, a1, a0};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {a3, a2, a1};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {a3, a2, a1, a0};
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
}
void CallFunctionDescriptor::InitializePlatformSpecific( void CallFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = {a1}; Register registers[] = {a1};
......
...@@ -88,27 +88,6 @@ void TypeofDescriptor::InitializePlatformSpecific( ...@@ -88,27 +88,6 @@ void TypeofDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers, NULL); data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
} }
void FastCloneRegExpDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {a3, a2, a1, a0};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {a3, a2, a1};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {a3, a2, a1, a0};
data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
}
void CallFunctionDescriptor::InitializePlatformSpecific( void CallFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = {a1}; Register registers[] = {a1};
......
...@@ -88,27 +88,6 @@ void TypeofDescriptor::InitializePlatformSpecific( ...@@ -88,27 +88,6 @@ void TypeofDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void FastCloneRegExpDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {r6, r5, r4, r3};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {r6, r5, r4};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {r6, r5, r4, r3};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void CallFunctionDescriptor::InitializePlatformSpecific( void CallFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = {r4}; Register registers[] = {r4};
......
...@@ -451,10 +451,9 @@ Handle<Object> InnerCreateBoilerplate(Isolate* isolate, ...@@ -451,10 +451,9 @@ Handle<Object> InnerCreateBoilerplate(Isolate* isolate,
template <typename Boilerplate> template <typename Boilerplate>
MaybeHandle<JSObject> CreateLiteral(Isolate* isolate, MaybeHandle<JSObject> CreateLiteral(Isolate* isolate,
Handle<JSFunction> closure, Handle<FeedbackVector> vector,
int literals_index, int literals_index,
Handle<HeapObject> description, int flags) { Handle<HeapObject> description, int flags) {
Handle<FeedbackVector> vector(closure->feedback_vector(), isolate);
FeedbackSlot literals_slot(FeedbackVector::ToSlot(literals_index)); FeedbackSlot literals_slot(FeedbackVector::ToSlot(literals_index));
CHECK(literals_slot.ToInt() < vector->length()); CHECK(literals_slot.ToInt() < vector->length());
Handle<Object> literal_site(vector->Get(literals_slot), isolate); Handle<Object> literal_site(vector->Get(literals_slot), isolate);
...@@ -521,36 +520,35 @@ MaybeHandle<JSObject> CreateLiteral(Isolate* isolate, ...@@ -521,36 +520,35 @@ MaybeHandle<JSObject> CreateLiteral(Isolate* isolate,
RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) { RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) {
HandleScope scope(isolate); HandleScope scope(isolate);
DCHECK_EQ(4, args.length()); DCHECK_EQ(4, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); CONVERT_ARG_HANDLE_CHECKED(FeedbackVector, vector, 0);
CONVERT_SMI_ARG_CHECKED(literals_index, 1); CONVERT_SMI_ARG_CHECKED(literals_index, 1);
CONVERT_ARG_HANDLE_CHECKED(BoilerplateDescription, description, 2); CONVERT_ARG_HANDLE_CHECKED(BoilerplateDescription, description, 2);
CONVERT_SMI_ARG_CHECKED(flags, 3); CONVERT_SMI_ARG_CHECKED(flags, 3);
RETURN_RESULT_OR_FAILURE( RETURN_RESULT_OR_FAILURE(
isolate, CreateLiteral<ObjectBoilerplate>( isolate, CreateLiteral<ObjectBoilerplate>(isolate, vector, literals_index,
isolate, closure, literals_index, description, flags)); description, flags));
} }
RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) { RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) {
HandleScope scope(isolate); HandleScope scope(isolate);
DCHECK_EQ(4, args.length()); DCHECK_EQ(4, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); CONVERT_ARG_HANDLE_CHECKED(FeedbackVector, vector, 0);
CONVERT_SMI_ARG_CHECKED(literals_index, 1); CONVERT_SMI_ARG_CHECKED(literals_index, 1);
CONVERT_ARG_HANDLE_CHECKED(ConstantElementsPair, elements, 2); CONVERT_ARG_HANDLE_CHECKED(ConstantElementsPair, elements, 2);
CONVERT_SMI_ARG_CHECKED(flags, 3); CONVERT_SMI_ARG_CHECKED(flags, 3);
RETURN_RESULT_OR_FAILURE( RETURN_RESULT_OR_FAILURE(
isolate, CreateLiteral<ArrayBoilerplate>(isolate, closure, literals_index, isolate, CreateLiteral<ArrayBoilerplate>(isolate, vector, literals_index,
elements, flags)); elements, flags));
} }
RUNTIME_FUNCTION(Runtime_CreateRegExpLiteral) { RUNTIME_FUNCTION(Runtime_CreateRegExpLiteral) {
HandleScope scope(isolate); HandleScope scope(isolate);
DCHECK_EQ(4, args.length()); DCHECK_EQ(4, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); CONVERT_ARG_HANDLE_CHECKED(FeedbackVector, vector, 0);
CONVERT_SMI_ARG_CHECKED(index, 1); CONVERT_SMI_ARG_CHECKED(index, 1);
CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2); CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2);
CONVERT_SMI_ARG_CHECKED(flags, 3); CONVERT_SMI_ARG_CHECKED(flags, 3);
Handle<FeedbackVector> vector(closure->feedback_vector(), isolate);
FeedbackSlot literal_slot(FeedbackVector::ToSlot(index)); FeedbackSlot literal_slot(FeedbackVector::ToSlot(index));
// Check if boilerplate exists. If not, create it first. // Check if boilerplate exists. If not, create it first.
......
...@@ -86,24 +86,6 @@ void TypeofDescriptor::InitializePlatformSpecific( ...@@ -86,24 +86,6 @@ void TypeofDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void FastCloneRegExpDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {r5, r4, r3, r2};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {r5, r4, r3};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {r5, r4, r3, r2};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void CallFunctionDescriptor::InitializePlatformSpecific( void CallFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = {r3}; Register registers[] = {r3};
......
...@@ -91,27 +91,6 @@ void TypeofDescriptor::InitializePlatformSpecific( ...@@ -91,27 +91,6 @@ void TypeofDescriptor::InitializePlatformSpecific(
// static // static
const Register TypeConversionDescriptor::ArgumentRegister() { return rax; } const Register TypeConversionDescriptor::ArgumentRegister() { return rax; }
void FastCloneRegExpDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {rdi, rax, rcx, rdx};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {rax, rbx, rcx};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {rax, rbx, rcx, rdx};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void CallFunctionDescriptor::InitializePlatformSpecific( void CallFunctionDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = {rdi}; Register registers[] = {rdi};
......
...@@ -40,8 +40,7 @@ class JSCreateLoweringTest : public TypedGraphTest { ...@@ -40,8 +40,7 @@ class JSCreateLoweringTest : public TypedGraphTest {
&machine); &machine);
// TODO(titzer): mock the GraphReducer here for better unit testing. // TODO(titzer): mock the GraphReducer here for better unit testing.
GraphReducer graph_reducer(zone(), graph()); GraphReducer graph_reducer(zone(), graph());
JSCreateLowering reducer(&graph_reducer, &deps_, &jsgraph, JSCreateLowering reducer(&graph_reducer, &deps_, &jsgraph, native_context(),
MaybeHandle<FeedbackVector>(), native_context(),
zone()); zone());
return reducer.Reduce(node); return reducer.Reduce(node);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment