Commit d21ed46d authored by cbruni's avatar cbruni Committed by Commit bot

[turbofan] Use fast stub for ForInPrepare and ForInNext

Review-Url: https://codereview.chromium.org/2684043002
Cr-Commit-Position: refs/heads/master@{#43040}
parent 2237106a
...@@ -910,6 +910,51 @@ TF_BUILTIN(ForInFilter, ObjectBuiltinsAssembler) { ...@@ -910,6 +910,51 @@ TF_BUILTIN(ForInFilter, ObjectBuiltinsAssembler) {
Return(ForInFilter(key, object, context)); Return(ForInFilter(key, object, context));
} }
TF_BUILTIN(ForInNext, ObjectBuiltinsAssembler) {
typedef ForInNextDescriptor Descriptor;
Label filter(this);
Node* object = Parameter(Descriptor::kObject);
Node* cache_array = Parameter(Descriptor::kCacheArray);
Node* cache_type = Parameter(Descriptor::kCacheType);
Node* index = Parameter(Descriptor::kIndex);
Node* context = Parameter(Descriptor::kContext);
Node* key = LoadFixedArrayElement(cache_array, SmiUntag(index));
Node* map = LoadMap(object);
GotoUnless(WordEqual(map, cache_type), &filter);
Return(key);
Bind(&filter);
Return(ForInFilter(key, object, context));
}
TF_BUILTIN(ForInPrepare, ObjectBuiltinsAssembler) {
typedef ForInPrepareDescriptor Descriptor;
Label use_cache(this), nothing_to_iterate(this), call_runtime(this);
Node* object = Parameter(Descriptor::kObject);
Node* context = Parameter(Descriptor::kContext);
CheckEnumCache(object, &use_cache, &call_runtime);
Bind(&use_cache);
Node* map = LoadMap(object);
Node* enum_length = EnumLength(map);
GotoIf(WordEqual(enum_length, SmiConstant(0)), &nothing_to_iterate);
Node* descriptors = LoadMapDescriptors(map);
Node* cache_offset =
LoadObjectField(descriptors, DescriptorArray::kEnumCacheOffset);
Node* enum_cache = LoadObjectField(
cache_offset, DescriptorArray::kEnumCacheBridgeCacheOffset);
Return(map, enum_cache, enum_length);
Bind(&nothing_to_iterate);
Node* zero = SmiConstant(0);
Return(zero, zero, zero);
Bind(&call_runtime);
TailCallRuntime(Runtime::kForInPrepare, context, object);
}
TF_BUILTIN(InstanceOf, ObjectBuiltinsAssembler) { TF_BUILTIN(InstanceOf, ObjectBuiltinsAssembler) {
typedef CompareDescriptor Descriptor; typedef CompareDescriptor Descriptor;
......
...@@ -98,7 +98,8 @@ Code* BuildWithCodeStubAssemblerJS(Isolate* isolate, ...@@ -98,7 +98,8 @@ Code* BuildWithCodeStubAssemblerJS(Isolate* isolate,
Code* BuildWithCodeStubAssemblerCS(Isolate* isolate, Code* BuildWithCodeStubAssemblerCS(Isolate* isolate,
CodeAssemblerGenerator generator, CodeAssemblerGenerator generator,
CallDescriptors::Key interface_descriptor, CallDescriptors::Key interface_descriptor,
Code::Flags flags, const char* name) { Code::Flags flags, const char* name,
int result_size) {
HandleScope scope(isolate); HandleScope scope(isolate);
Zone zone(isolate->allocator(), ZONE_NAME); Zone zone(isolate->allocator(), ZONE_NAME);
// The interface descriptor with given key must be initialized at this point // The interface descriptor with given key must be initialized at this point
...@@ -106,7 +107,8 @@ Code* BuildWithCodeStubAssemblerCS(Isolate* isolate, ...@@ -106,7 +107,8 @@ Code* BuildWithCodeStubAssemblerCS(Isolate* isolate,
CallInterfaceDescriptor descriptor(isolate, interface_descriptor); CallInterfaceDescriptor descriptor(isolate, interface_descriptor);
// Ensure descriptor is already initialized. // Ensure descriptor is already initialized.
DCHECK_LE(0, descriptor.GetRegisterParameterCount()); DCHECK_LE(0, descriptor.GetRegisterParameterCount());
compiler::CodeAssemblerState state(isolate, &zone, descriptor, flags, name); compiler::CodeAssemblerState state(isolate, &zone, descriptor, flags, name,
result_size);
generator(&state); generator(&state);
Handle<Code> code = compiler::CodeAssembler::GenerateCode(&state); Handle<Code> code = compiler::CodeAssembler::GenerateCode(&state);
PostBuildProfileAndTracing(isolate, *code, name); PostBuildProfileAndTracing(isolate, *code, name);
...@@ -136,11 +138,11 @@ void Builtins::SetUp(Isolate* isolate, bool create_heap_objects) { ...@@ -136,11 +138,11 @@ void Builtins::SetUp(Isolate* isolate, bool create_heap_objects) {
code = BuildWithCodeStubAssemblerJS(isolate, &Generate_##Name, Argc, \ code = BuildWithCodeStubAssemblerJS(isolate, &Generate_##Name, Argc, \
kBuiltinFlags, #Name); \ kBuiltinFlags, #Name); \
builtins_[index++] = code; builtins_[index++] = code;
#define BUILD_TFS(Name, Kind, Extra, InterfaceDescriptor) \ #define BUILD_TFS(Name, Kind, Extra, InterfaceDescriptor, result_size) \
{ InterfaceDescriptor##Descriptor descriptor(isolate); } \ { InterfaceDescriptor##Descriptor descriptor(isolate); } \
code = BuildWithCodeStubAssemblerCS( \ code = BuildWithCodeStubAssemblerCS( \
isolate, &Generate_##Name, CallDescriptors::InterfaceDescriptor, \ isolate, &Generate_##Name, CallDescriptors::InterfaceDescriptor, \
Code::ComputeFlags(Code::Kind, Extra), #Name); \ Code::ComputeFlags(Code::Kind, Extra), #Name, result_size); \
builtins_[index++] = code; builtins_[index++] = code;
#define BUILD_ASM(Name) \ #define BUILD_ASM(Name) \
code = \ code = \
......
This diff is collapsed.
...@@ -193,7 +193,7 @@ Callable CodeFactory::StringFromCharCode(Isolate* isolate) { ...@@ -193,7 +193,7 @@ Callable CodeFactory::StringFromCharCode(Isolate* isolate) {
return Callable(code, BuiltinDescriptor(isolate)); return Callable(code, BuiltinDescriptor(isolate));
} }
#define DECLARE_TFS(Name, Kind, Extra, InterfaceDescriptor) \ #define DECLARE_TFS(Name, Kind, Extra, InterfaceDescriptor, result_size) \
typedef InterfaceDescriptor##Descriptor Name##Descriptor; typedef InterfaceDescriptor##Descriptor Name##Descriptor;
BUILTIN_LIST(IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, DECLARE_TFS, BUILTIN_LIST(IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, DECLARE_TFS,
IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN) IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN)
...@@ -363,6 +363,18 @@ Callable CodeFactory::FastNewStrictArguments(Isolate* isolate) { ...@@ -363,6 +363,18 @@ Callable CodeFactory::FastNewStrictArguments(Isolate* isolate) {
FastNewRestParameterDescriptor(isolate)); FastNewRestParameterDescriptor(isolate));
} }
// static
Callable CodeFactory::ForInPrepare(Isolate* isolate) {
return Callable(isolate->builtins()->ForInPrepare(),
ForInPrepareDescriptor(isolate));
}
// static
Callable CodeFactory::ForInNext(Isolate* isolate) {
return Callable(isolate->builtins()->ForInNext(),
ForInNextDescriptor(isolate));
}
// static // static
Callable CodeFactory::AllocateHeapNumber(Isolate* isolate) { Callable CodeFactory::AllocateHeapNumber(Isolate* isolate) {
AllocateHeapNumberStub stub(isolate); AllocateHeapNumberStub stub(isolate);
......
...@@ -152,6 +152,9 @@ class V8_EXPORT_PRIVATE CodeFactory final { ...@@ -152,6 +152,9 @@ class V8_EXPORT_PRIVATE CodeFactory final {
static Callable FastNewSloppyArguments(Isolate* isolate); static Callable FastNewSloppyArguments(Isolate* isolate);
static Callable FastNewStrictArguments(Isolate* isolate); static Callable FastNewStrictArguments(Isolate* isolate);
static Callable ForInPrepare(Isolate* isolate);
static Callable ForInNext(Isolate* isolate);
static Callable CopyFastSmiOrObjectElements(Isolate* isolate); static Callable CopyFastSmiOrObjectElements(Isolate* isolate);
static Callable GrowFastDoubleElements(Isolate* isolate); static Callable GrowFastDoubleElements(Isolate* isolate);
static Callable GrowFastSmiOrObjectElements(Isolate* isolate); static Callable GrowFastSmiOrObjectElements(Isolate* isolate);
......
...@@ -260,6 +260,14 @@ void CodeAssembler::Return(Node* value) { ...@@ -260,6 +260,14 @@ void CodeAssembler::Return(Node* value) {
return raw_assembler()->Return(value); return raw_assembler()->Return(value);
} }
void CodeAssembler::Return(Node* value1, Node* value2) {
return raw_assembler()->Return(value1, value2);
}
void CodeAssembler::Return(Node* value1, Node* value2, Node* value3) {
return raw_assembler()->Return(value1, value2, value3);
}
void CodeAssembler::PopAndReturn(Node* pop, Node* value) { void CodeAssembler::PopAndReturn(Node* pop, Node* value) {
return raw_assembler()->PopAndReturn(pop, value); return raw_assembler()->PopAndReturn(pop, value);
} }
......
...@@ -229,6 +229,8 @@ class V8_EXPORT_PRIVATE CodeAssembler { ...@@ -229,6 +229,8 @@ class V8_EXPORT_PRIVATE CodeAssembler {
Node* Parameter(int value); Node* Parameter(int value);
Node* GetJSContextParameter(); Node* GetJSContextParameter();
void Return(Node* value); void Return(Node* value);
void Return(Node* value1, Node* value2);
void Return(Node* value1, Node* value2, Node* value3);
void PopAndReturn(Node* pop, Node* value); void PopAndReturn(Node* pop, Node* value);
void DebugBreak(); void DebugBreak();
......
...@@ -88,11 +88,12 @@ void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable, ...@@ -88,11 +88,12 @@ void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable,
void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable, void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable,
CallDescriptor::Flags flags, CallDescriptor::Flags flags,
Operator::Properties properties) { Operator::Properties properties,
int result_size) {
const CallInterfaceDescriptor& descriptor = callable.descriptor(); const CallInterfaceDescriptor& descriptor = callable.descriptor();
CallDescriptor* desc = Linkage::GetStubCallDescriptor( CallDescriptor* desc = Linkage::GetStubCallDescriptor(
isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), flags, isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), flags,
properties); properties, MachineType::AnyTagged(), result_size);
Node* stub_code = jsgraph()->HeapConstant(callable.code()); Node* stub_code = jsgraph()->HeapConstant(callable.code());
node->InsertInput(zone(), 0, stub_code); node->InsertInput(zone(), 0, stub_code);
NodeProperties::ChangeOp(node, common()->Call(desc)); NodeProperties::ChangeOp(node, common()->Call(desc));
...@@ -586,12 +587,15 @@ void JSGenericLowering::LowerJSConvertReceiver(Node* node) { ...@@ -586,12 +587,15 @@ void JSGenericLowering::LowerJSConvertReceiver(Node* node) {
} }
void JSGenericLowering::LowerJSForInNext(Node* node) { void JSGenericLowering::LowerJSForInNext(Node* node) {
ReplaceWithRuntimeCall(node, Runtime::kForInNext); CallDescriptor::Flags flags = FrameStateFlagForCall(node);
Callable callable = CodeFactory::ForInNext(isolate());
ReplaceWithStubCall(node, callable, flags);
} }
void JSGenericLowering::LowerJSForInPrepare(Node* node) { void JSGenericLowering::LowerJSForInPrepare(Node* node) {
ReplaceWithRuntimeCall(node, Runtime::kForInPrepare); CallDescriptor::Flags flags = FrameStateFlagForCall(node);
Callable callable = CodeFactory::ForInPrepare(isolate());
ReplaceWithStubCall(node, callable, flags, node->op()->properties(), 3);
} }
void JSGenericLowering::LowerJSLoadMessage(Node* node) { void JSGenericLowering::LowerJSLoadMessage(Node* node) {
......
...@@ -38,7 +38,8 @@ class JSGenericLowering final : public Reducer { ...@@ -38,7 +38,8 @@ class JSGenericLowering final : public Reducer {
// Helpers to replace existing nodes with a generic call. // Helpers to replace existing nodes with a generic call.
void ReplaceWithStubCall(Node* node, Callable c, CallDescriptor::Flags flags); void ReplaceWithStubCall(Node* node, Callable c, CallDescriptor::Flags flags);
void ReplaceWithStubCall(Node* node, Callable c, CallDescriptor::Flags flags, void ReplaceWithStubCall(Node* node, Callable c, CallDescriptor::Flags flags,
Operator::Properties properties); Operator::Properties properties,
int result_size = 1);
void ReplaceWithRuntimeCall(Node* node, Runtime::FunctionId f, int args = -1); void ReplaceWithRuntimeCall(Node* node, Runtime::FunctionId f, int args = -1);
Zone* zone() const; Zone* zone() const;
......
...@@ -87,6 +87,8 @@ class PlatformInterfaceDescriptor; ...@@ -87,6 +87,8 @@ class PlatformInterfaceDescriptor;
V(CreateIterResultObject) \ V(CreateIterResultObject) \
V(HasProperty) \ V(HasProperty) \
V(ForInFilter) \ V(ForInFilter) \
V(ForInNext) \
V(ForInPrepare) \
V(GetProperty) \ V(GetProperty) \
V(CallHandler) \ V(CallHandler) \
V(ArgumentAdaptor) \ V(ArgumentAdaptor) \
...@@ -531,6 +533,20 @@ class ForInFilterDescriptor final : public CallInterfaceDescriptor { ...@@ -531,6 +533,20 @@ class ForInFilterDescriptor final : public CallInterfaceDescriptor {
kParameterCount) kParameterCount)
}; };
class ForInNextDescriptor final : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kObject, kCacheArray, kCacheType, kIndex)
DECLARE_DEFAULT_DESCRIPTOR(ForInNextDescriptor, CallInterfaceDescriptor,
kParameterCount)
};
class ForInPrepareDescriptor final : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kObject)
DECLARE_DEFAULT_DESCRIPTOR(ForInPrepareDescriptor, CallInterfaceDescriptor,
kParameterCount)
};
class GetPropertyDescriptor final : public CallInterfaceDescriptor { class GetPropertyDescriptor final : public CallInterfaceDescriptor {
public: public:
DEFINE_PARAMETERS(kObject, kKey) DEFINE_PARAMETERS(kObject, kKey)
......
...@@ -160,22 +160,5 @@ RUNTIME_FUNCTION(Runtime_ForInFilter) { ...@@ -160,22 +160,5 @@ RUNTIME_FUNCTION(Runtime_ForInFilter) {
HasEnumerableProperty(isolate, receiver, key)); HasEnumerableProperty(isolate, receiver, key));
} }
RUNTIME_FUNCTION(Runtime_ForInNext) {
HandleScope scope(isolate);
DCHECK_EQ(4, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
CONVERT_ARG_HANDLE_CHECKED(FixedArray, cache_array, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, cache_type, 2);
CONVERT_SMI_ARG_CHECKED(index, 3);
Handle<Object> key = handle(cache_array->get(index), isolate);
// Don't need filtering if expected map still matches that of the receiver.
if (receiver->map() == *cache_type) {
return *key;
}
RETURN_RESULT_OR_FAILURE(isolate,
HasEnumerableProperty(isolate, receiver, key));
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -209,8 +209,7 @@ namespace internal { ...@@ -209,8 +209,7 @@ namespace internal {
#define FOR_EACH_INTRINSIC_FORIN(F) \ #define FOR_EACH_INTRINSIC_FORIN(F) \
F(ForInEnumerate, 1, 1) \ F(ForInEnumerate, 1, 1) \
F(ForInFilter, 2, 1) \ F(ForInFilter, 2, 1) \
F(ForInHasProperty, 2, 1) \ F(ForInHasProperty, 2, 1)
F(ForInNext, 4, 1)
#define FOR_EACH_INTRINSIC_INTERPRETER(F) \ #define FOR_EACH_INTRINSIC_INTERPRETER(F) \
F(InterpreterNewClosure, 4, 1) \ F(InterpreterNewClosure, 4, 1) \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment