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