From 855b88ae5a569b236cab0211a5702ed2ad4ee0c3 Mon Sep 17 00:00:00 2001 From: Benedikt Meurer Date: Mon, 25 Sep 2017 14:30:25 +0200 Subject: [PATCH] [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 Reviewed-by: Yang Guo Cr-Commit-Position: refs/heads/master@{#48140} --- src/arm/interface-descriptors-arm.cc | 21 --- src/arm64/interface-descriptors-arm64.cc | 32 ----- src/ast/ast.cc | 2 +- src/ast/ast.h | 4 +- src/builtins/builtins-constructor-gen.cc | 121 +++++++----------- src/builtins/builtins-constructor-gen.h | 18 ++- src/builtins/builtins-definitions.h | 11 +- src/builtins/builtins.cc | 13 -- src/builtins/builtins.h | 1 - src/code-factory.cc | 7 - src/code-factory.h | 3 - src/compiler/bytecode-graph-builder.cc | 32 +++-- src/compiler/js-create-lowering.cc | 93 +++++--------- src/compiler/js-create-lowering.h | 6 - src/compiler/js-generic-lowering.cc | 41 +++--- src/compiler/js-operator.cc | 87 +++++++------ src/compiler/js-operator.h | 29 +++-- src/compiler/pipeline.cc | 4 +- src/ia32/interface-descriptors-ia32.cc | 21 --- src/interface-descriptors.cc | 20 --- src/interface-descriptors.h | 26 ---- src/interpreter/bytecode-generator.cc | 2 +- src/interpreter/interpreter-generator.cc | 47 +++---- src/mips/interface-descriptors-mips.cc | 21 --- src/mips64/interface-descriptors-mips64.cc | 21 --- src/ppc/interface-descriptors-ppc.cc | 21 --- src/runtime/runtime-literals.cc | 16 +-- src/s390/interface-descriptors-s390.cc | 18 --- src/x64/interface-descriptors-x64.cc | 21 --- .../compiler/js-create-lowering-unittest.cc | 3 +- 30 files changed, 227 insertions(+), 535 deletions(-) diff --git a/src/arm/interface-descriptors-arm.cc b/src/arm/interface-descriptors-arm.cc index d964b0743f..fb7076d33f 100644 --- a/src/arm/interface-descriptors-arm.cc +++ b/src/arm/interface-descriptors-arm.cc @@ -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}; diff --git a/src/arm64/interface-descriptors-arm64.cc b/src/arm64/interface-descriptors-arm64.cc index f5dea3abf7..6f0a600aa2 100644 --- a/src/arm64/interface-descriptors-arm64.cc +++ b/src/arm64/interface-descriptors-arm64.cc @@ -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 diff --git a/src/ast/ast.cc b/src/ast/ast.cc index f57952e8ab..ca01039644 100644 --- a/src/ast/ast.cc +++ b/src/ast/ast.cc @@ -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() && diff --git a/src/ast/ast.h b/src/ast/ast.h index 6b191428ed..0253e6651e 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -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. diff --git a/src/builtins/builtins-constructor-gen.cc b/src/builtins/builtins-constructor-gen.cc index fc0b8c8ef4..3b3e3c7821 100644 --- a/src/builtins/builtins-constructor-gen.cc +++ b/src/builtins/builtins-constructor-gen.cc @@ -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 = diff --git a/src/builtins/builtins-constructor-gen.h b/src/builtins/builtins-constructor-gen.h index 969b663929..b889100148 100644 --- a/src/builtins/builtins-constructor-gen.h +++ b/src/builtins/builtins-constructor-gen.h @@ -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); diff --git a/src/builtins/builtins-definitions.h b/src/builtins/builtins-definitions.h index baa8a58d2a..015929e132 100644 --- a/src/builtins/builtins-definitions.h +++ b/src/builtins/builtins-definitions.h @@ -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) \ \ diff --git a/src/builtins/builtins.cc b/src/builtins/builtins.cc index d407087d54..9cd6821907 100644 --- a/src/builtins/builtins.cc +++ b/src/builtins/builtins.cc @@ -113,19 +113,6 @@ Handle Builtins::NewFunctionContext(ScopeType scope_type) { return Handle::null(); } -Handle 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::null(); -} - Handle Builtins::NonPrimitiveToPrimitive(ToPrimitiveHint hint) { switch (hint) { case ToPrimitiveHint::kDefault: diff --git a/src/builtins/builtins.h b/src/builtins/builtins.h index 405aed10d6..e28feb7efe 100644 --- a/src/builtins/builtins.h +++ b/src/builtins/builtins.h @@ -68,7 +68,6 @@ class Builtins { InterpreterPushArgsMode mode); Handle InterpreterPushArgsThenConstruct(InterpreterPushArgsMode mode); Handle NewFunctionContext(ScopeType scope_type); - Handle NewCloneShallowArray(AllocationSiteMode allocation_mode); Handle JSConstructStubGeneric(); // Used by BuiltinDeserializer. diff --git a/src/code-factory.cc b/src/code-factory.cc index 81b06fa0cd..2ef34f4a8a 100644 --- a/src/code-factory.cc +++ b/src/code-factory.cc @@ -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) { diff --git a/src/code-factory.h b/src/code-factory.h index 96919db584..2ecb72082c 100644 --- a/src/code-factory.h +++ b/src/code-factory.h @@ -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); diff --git a/src/compiler/bytecode-graph-builder.cc b/src/compiler/bytecode-graph-builder.cc index 2357f4aa76..98fd007c3b 100644 --- a/src/compiler/bytecode-graph-builder.cc +++ b/src/compiler/bytecode-graph-builder.cc @@ -1480,11 +1480,11 @@ void BytecodeGraphBuilder::VisitCreateRestParameter() { void BytecodeGraphBuilder::VisitCreateRegExpLiteral() { Handle constant_pattern = Handle::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 constant_elements = Handle::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 constant_properties = Handle::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); } diff --git a/src/compiler/js-create-lowering.cc b/src/compiler/js-create-lowering.cc index 6efdc2906e..6e6a5c57ed 100644 --- a/src/compiler/js-create-lowering.cc +++ b/src/compiler/js-create-lowering.cc @@ -854,41 +854,35 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralArrayOrObject(Node* node) { Node* effect = NodeProperties::GetEffectInput(node); Node* control = NodeProperties::GetControlInput(node); - Handle feedback_vector; - if (GetSpecializationFeedbackVector(node).ToHandle(&feedback_vector)) { - FeedbackSlot slot(FeedbackVector::ToSlot(p.index())); - Handle literal(feedback_vector->Get(slot), isolate()); - if (literal->IsAllocationSite()) { - Handle site = Handle::cast(literal); - Handle 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 feedback(p.feedback().vector()->Get(p.feedback().slot()), + isolate()); + if (feedback->IsAllocationSite()) { + Handle site = Handle::cast(feedback); + Handle 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(node); - Handle feedback_vector; - if (GetSpecializationFeedbackVector(node).ToHandle(&feedback_vector)) { - FeedbackSlot slot(FeedbackVector::ToSlot(literal_index)); - Handle raw_site(feedback_vector->Get(slot), isolate()); - if (raw_site->IsAllocationSite()) { - Handle site = Handle::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 feedback(p.feedback().vector()->Get(p.feedback().slot()), + isolate()); + if (feedback->IsAllocationSite()) { + Handle site = Handle::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 feedback_vector; - if (GetSpecializationFeedbackVector(node).ToHandle(&feedback_vector)) { - FeedbackSlot slot(FeedbackVector::ToSlot(p.index())); - Handle maybe_boilerplate(feedback_vector->Get(slot), isolate()); - if (maybe_boilerplate->IsJSRegExp()) { - Node* value = effect = AllocateLiteralRegExp( - effect, control, Handle::cast(maybe_boilerplate)); - ReplaceWithValue(node, value, effect, control); - return Replace(value); - } + Handle feedback(p.feedback().vector()->Get(p.feedback().slot()), + isolate()); + if (feedback->IsJSRegExp()) { + Handle boilerplate = Handle::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 JSCreateLowering::GetSpecializationFeedbackVector( - Node* node) { - Node* const closure = NodeProperties::GetValueInput(node, 0); - switch (closure->opcode()) { - case IrOpcode::kHeapConstant: { - Handle object = OpParameter>(closure); - return handle(Handle::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(); -} - Factory* JSCreateLowering::factory() const { return isolate()->factory(); } Graph* JSCreateLowering::graph() const { return jsgraph()->graph(); } diff --git a/src/compiler/js-create-lowering.h b/src/compiler/js-create-lowering.h index 88832399b9..307e054a75 100644 --- a/src/compiler/js-create-lowering.h +++ b/src/compiler/js-create-lowering.h @@ -34,12 +34,10 @@ class V8_EXPORT_PRIVATE JSCreateLowering final public: JSCreateLowering(Editor* editor, CompilationDependencies* dependencies, JSGraph* jsgraph, - MaybeHandle feedback_vector, Handle 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 site); - // Infers the FeedbackVector to use for a given {node}. - MaybeHandle 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 const feedback_vector_; Handle const native_context_; Zone* const zone_; }; diff --git a/src/compiler/js-generic-lowering.cc b/src/compiler/js-generic-lowering.cc index 077be69bb9..4d7b7972a9 100644 --- a/src/compiler/js-generic-lowering.cc +++ b/src/compiler/js-generic-lowering.cc @@ -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(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); } diff --git a/src/compiler/js-operator.cc b/src/compiler/js-operator.cc index be1752d81f..7b1df6e5a9 100644 --- a/src/compiler/js-operator.cc +++ b/src/compiler/js-operator.cc @@ -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(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 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( // -- - IrOpcode::kJSCreateLiteralArray, Operator::kNoProperties, // opcode - "JSCreateLiteralArray", // name - 1, 1, 1, 1, 1, 2, // counts - parameters); // parameter + Handle 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( // -- + 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( // -- - 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( // -- + IrOpcode::kJSCreateEmptyLiteralArray, // opcode + Operator::kEliminatable, // properties + "JSCreateEmptyLiteralArray", // name + 0, 1, 1, 1, 1, 0, // counts + parameters); // parameter } const Operator* JSOperatorBuilder::CreateLiteralObject( - Handle 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( // -- - IrOpcode::kJSCreateLiteralObject, Operator::kNoProperties, // opcode - "JSCreateLiteralObject", // name - 1, 1, 1, 1, 1, 2, // counts - parameters); // parameter + Handle 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( // -- + 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 constant_pattern, int literal_flags, int literal_index) { - CreateLiteralParameters parameters(constant_pattern, -1, literal_flags, - literal_index); - return new (zone()) Operator1( // -- - IrOpcode::kJSCreateLiteralRegExp, Operator::kNoProperties, // opcode - "JSCreateLiteralRegExp", // name - 1, 1, 1, 1, 1, 2, // counts - parameters); // parameter + Handle constant_pattern, VectorSlotPair const& feedback, + int literal_flags) { + CreateLiteralParameters parameters(constant_pattern, feedback, -1, + literal_flags); + return new (zone()) Operator1( // -- + IrOpcode::kJSCreateLiteralRegExp, // opcode + Operator::kNoProperties, // properties + "JSCreateLiteralRegExp", // name + 0, 1, 1, 1, 1, 2, // counts + parameters); // parameter } const Operator* JSOperatorBuilder::CreateFunctionContext(int slot_count, diff --git a/src/compiler/js-operator.h b/src/compiler/js-operator.h index 279b88d8e8..0d47005824 100644 --- a/src/compiler/js-operator.h +++ b/src/compiler/js-operator.h @@ -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 constant, int length, int flags, - int index) - : constant_(constant), length_(length), flags_(flags), index_(index) {} + CreateLiteralParameters(Handle constant, + VectorSlotPair const& feedback, int length, int flags) + : constant_(constant), + feedback_(feedback), + length_(length), + flags_(flags) {} Handle 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 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 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 constant, - int literal_flags, int literal_index, + VectorSlotPair const& feedback, + int literal_flags, int number_of_properties); const Operator* CreateLiteralRegExp(Handle 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( diff --git a/src/compiler/pipeline.cc b/src/compiler/pipeline.cc index 7ec51d236b..07cf08073f 100644 --- a/src/compiler/pipeline.cc +++ b/src/compiler/pipeline.cc @@ -1028,11 +1028,9 @@ struct TypedLoweringPhase { JSBuiltinReducer builtin_reducer( &graph_reducer, data->jsgraph(), data->info()->dependencies(), data->native_context()); - Handle 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()); diff --git a/src/ia32/interface-descriptors-ia32.cc b/src/ia32/interface-descriptors-ia32.cc index 1c97b535b9..95c1dc4a5e 100644 --- a/src/ia32/interface-descriptors-ia32.cc +++ b/src/ia32/interface-descriptors-ia32.cc @@ -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}; diff --git a/src/interface-descriptors.cc b/src/interface-descriptors.cc index 1703187ffc..94ad2efc72 100644 --- a/src/interface-descriptors.cc +++ b/src/interface-descriptors.cc @@ -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 diff --git a/src/interface-descriptors.h b/src/interface-descriptors.h index b15a3172d3..e6cdf7fdd2 100644 --- a/src/interface-descriptors.h +++ b/src/interface-descriptors.h @@ -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) diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc index c1b838e1f5..68b2838c1d 100644 --- a/src/interpreter/bytecode-generator.cc +++ b/src/interpreter/bytecode-generator.cc @@ -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); diff --git a/src/interpreter/interpreter-generator.cc b/src/interpreter/interpreter-generator.cc index fb02b948df..2329d88736 100644 --- a/src/interpreter/interpreter-generator.cc +++ b/src/interpreter/interpreter-generator.cc @@ -2643,15 +2643,15 @@ IGNITION_HANDLER(SwitchOnSmiNoFeedback, InterpreterAssembler) { // Creates a regular expression literal for literal index with // and the pattern in . 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 with // CreateArrayLiteral flags and constant elements in . 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 . 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 with // CreateObjectLiteralFlags and constant elements in . 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(); diff --git a/src/mips/interface-descriptors-mips.cc b/src/mips/interface-descriptors-mips.cc index 2e8e2158fc..92e0e958b7 100644 --- a/src/mips/interface-descriptors-mips.cc +++ b/src/mips/interface-descriptors-mips.cc @@ -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}; diff --git a/src/mips64/interface-descriptors-mips64.cc b/src/mips64/interface-descriptors-mips64.cc index 86ea4b28bd..679a10ad68 100644 --- a/src/mips64/interface-descriptors-mips64.cc +++ b/src/mips64/interface-descriptors-mips64.cc @@ -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}; diff --git a/src/ppc/interface-descriptors-ppc.cc b/src/ppc/interface-descriptors-ppc.cc index caad1657b7..7f0b8a5961 100644 --- a/src/ppc/interface-descriptors-ppc.cc +++ b/src/ppc/interface-descriptors-ppc.cc @@ -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}; diff --git a/src/runtime/runtime-literals.cc b/src/runtime/runtime-literals.cc index e384c4872d..0dc15793a9 100644 --- a/src/runtime/runtime-literals.cc +++ b/src/runtime/runtime-literals.cc @@ -451,10 +451,9 @@ Handle InnerCreateBoilerplate(Isolate* isolate, template MaybeHandle CreateLiteral(Isolate* isolate, - Handle closure, + Handle vector, int literals_index, Handle description, int flags) { - Handle vector(closure->feedback_vector(), isolate); FeedbackSlot literals_slot(FeedbackVector::ToSlot(literals_index)); CHECK(literals_slot.ToInt() < vector->length()); Handle literal_site(vector->Get(literals_slot), isolate); @@ -521,36 +520,35 @@ MaybeHandle 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( - isolate, closure, literals_index, description, flags)); + isolate, CreateLiteral(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(isolate, closure, literals_index, + isolate, CreateLiteral(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 vector(closure->feedback_vector(), isolate); FeedbackSlot literal_slot(FeedbackVector::ToSlot(index)); // Check if boilerplate exists. If not, create it first. diff --git a/src/s390/interface-descriptors-s390.cc b/src/s390/interface-descriptors-s390.cc index a91b924374..5e27f59226 100644 --- a/src/s390/interface-descriptors-s390.cc +++ b/src/s390/interface-descriptors-s390.cc @@ -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}; diff --git a/src/x64/interface-descriptors-x64.cc b/src/x64/interface-descriptors-x64.cc index b9e3bcc8df..a978a14aaa 100644 --- a/src/x64/interface-descriptors-x64.cc +++ b/src/x64/interface-descriptors-x64.cc @@ -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}; diff --git a/test/unittests/compiler/js-create-lowering-unittest.cc b/test/unittests/compiler/js-create-lowering-unittest.cc index ccbe118ae5..e185c64795 100644 --- a/test/unittests/compiler/js-create-lowering-unittest.cc +++ b/test/unittests/compiler/js-create-lowering-unittest.cc @@ -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(), native_context(), + JSCreateLowering reducer(&graph_reducer, &deps_, &jsgraph, native_context(), zone()); return reducer.Reduce(node); }