Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(543)

Side by Side Diff: src/code-stubs.cc

Issue 1922523002: [Interpreter] Use FastCloneShallowObjectStub in CreateObjectLiteral bytecode. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address Toon's comments Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/code-stubs.h" 5 #include "src/code-stubs.h"
6 6
7 #include <sstream> 7 #include <sstream>
8 8
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 3789 matching lines...) Expand 10 before | Expand all | Expand 10 after
3800 &if_keyisinvalid); 3800 &if_keyisinvalid);
3801 assembler->Bind(&if_keyispositivesmi); 3801 assembler->Bind(&if_keyispositivesmi);
3802 assembler->TailCallRuntime(Runtime::kLoadElementWithInterceptor, context, 3802 assembler->TailCallRuntime(Runtime::kLoadElementWithInterceptor, context,
3803 receiver, key); 3803 receiver, key);
3804 3804
3805 assembler->Bind(&if_keyisinvalid); 3805 assembler->Bind(&if_keyisinvalid);
3806 assembler->TailCallRuntime(Runtime::kKeyedLoadIC_Miss, context, receiver, key, 3806 assembler->TailCallRuntime(Runtime::kKeyedLoadIC_Miss, context, receiver, key,
3807 slot, vector); 3807 slot, vector);
3808 } 3808 }
3809 3809
3810 void FastCloneShallowObjectStub::GenerateAssembly( 3810 // static
3811 CodeStubAssembler* assembler) const { 3811 bool FastCloneShallowObjectStub::IsSupported(ObjectLiteral* expr) {
3812 typedef CodeStubAssembler::Label Label; 3812 // FastCloneShallowObjectStub doesn't copy elements, and object literals don't
3813 // support copy-on-write (COW) elements for now.
3814 // TODO(mvstanton): make object literals support COW elements.
3815 return expr->fast_elements() && expr->has_shallow_properties() &&
3816 expr->properties_count() <= kMaximumClonedProperties;
3817 }
3818
3819 // static
3820 int FastCloneShallowObjectStub::PropertiesCount(int literal_length) {
Michael Starzinger 2016/04/29 08:37:31 Non-actionable question just for my understanding:
Toon Verwaest 2016/04/29 09:07:10 Yes, they are the same; and they have to be the sa
Michael Starzinger 2016/04/29 09:51:36 Acknowledged. Thanks, makes sense. +1 on eventual
rmcilroy 2016/04/29 13:53:21 Ack. Added a TODO towards unification.
3821 return literal_length == 0
3822 ? JSObject::kInitialGlobalObjectUnusedPropertiesCount
3823 : literal_length;
3824 }
3825
3826 // static
3827 compiler::Node* FastCloneShallowObjectStub::GenerateFastPath(
3828 CodeStubAssembler* assembler, compiler::CodeAssembler::Label* call_runtime,
3829 compiler::Node* closure, compiler::Node* literals_index,
3830 compiler::Node* properties_count) {
3813 typedef compiler::Node Node; 3831 typedef compiler::Node Node;
3814 Label call_runtime(assembler); 3832 typedef compiler::CodeAssembler::Label Label;
3815 Node* closure = assembler->Parameter(0); 3833 typedef compiler::CodeAssembler::Variable Variable;
3816 Node* literals_index = assembler->Parameter(1);
3817 3834
3818 Node* undefined = assembler->UndefinedConstant(); 3835 Node* undefined = assembler->UndefinedConstant();
3819 Node* literals_array = 3836 Node* literals_array =
3820 assembler->LoadObjectField(closure, JSFunction::kLiteralsOffset); 3837 assembler->LoadObjectField(closure, JSFunction::kLiteralsOffset);
3821 Node* allocation_site = assembler->LoadFixedArrayElementSmiIndex( 3838 Node* allocation_site = assembler->LoadFixedArrayElementSmiIndex(
3822 literals_array, literals_index, 3839 literals_array, literals_index,
3823 LiteralsArray::kFirstLiteralIndex * kPointerSize); 3840 LiteralsArray::kFirstLiteralIndex * kPointerSize);
3824 assembler->GotoIf(assembler->WordEqual(allocation_site, undefined), 3841 assembler->GotoIf(assembler->WordEqual(allocation_site, undefined),
3825 &call_runtime); 3842 call_runtime);
3826 3843
3844 // Calculate the object and allocation size based on the properties count.
3845 Node* object_size = assembler->IntPtrAdd(
3846 assembler->WordShl(properties_count, kPointerSizeLog2),
3847 assembler->IntPtrConstant(JSObject::kHeaderSize));
3848 Node* allocation_size = object_size;
3849 if (FLAG_allocation_site_pretenuring) {
3850 allocation_size = assembler->IntPtrAdd(
3851 object_size, assembler->IntPtrConstant(AllocationMemento::kSize));
3852 }
3827 Node* boilerplate = assembler->LoadObjectField( 3853 Node* boilerplate = assembler->LoadObjectField(
3828 allocation_site, AllocationSite::kTransitionInfoOffset); 3854 allocation_site, AllocationSite::kTransitionInfoOffset);
3829
3830 int length = this->length();
3831 if (length == 0) {
3832 length = JSObject::kInitialGlobalObjectUnusedPropertiesCount;
3833 }
3834 int allocation_size = JSObject::kHeaderSize + length * kPointerSize;
3835 int object_size = allocation_size;
3836 if (FLAG_allocation_site_pretenuring) {
3837 allocation_size += AllocationMemento::kSize;
3838 }
3839
3840 Node* boilerplate_map = assembler->LoadMap(boilerplate); 3855 Node* boilerplate_map = assembler->LoadMap(boilerplate);
3841 Node* instance_size = assembler->LoadMapInstanceSize(boilerplate_map); 3856 Node* instance_size = assembler->LoadMapInstanceSize(boilerplate_map);
3842 Node* size_in_words = 3857 Node* size_in_words = assembler->WordShr(object_size, kPointerSizeLog2);
3843 assembler->Int32Constant(object_size >> kPointerSizeLog2);
3844 assembler->GotoUnless(assembler->Word32Equal(instance_size, size_in_words), 3858 assembler->GotoUnless(assembler->Word32Equal(instance_size, size_in_words),
3845 &call_runtime); 3859 call_runtime);
3846 3860
3847 Node* copy = assembler->Allocate(allocation_size); 3861 Node* copy = assembler->Allocate(allocation_size);
3848 3862
3849 for (int i = 0; i < object_size; i += kPointerSize) { 3863 // Copy boilerplate elements.
3864 Variable offset(assembler, MachineType::PointerRepresentation());
3865 offset.Bind(assembler->IntPtrConstant(-kHeapObjectTag));
3866 Node* end_offset = assembler->IntPtrAdd(object_size, offset.value());
3867 Label loop_body(assembler, &offset), loop_check(assembler, &offset);
3868 // We should always have an object size greater than zero.
3869 assembler->Goto(&loop_body);
3870 assembler->Bind(&loop_body);
3871 {
3850 // The Allocate above guarantees that the copy lies in new space. This 3872 // The Allocate above guarantees that the copy lies in new space. This
3851 // allows us to skip write barriers. This is necessary since we may also be 3873 // allows us to skip write barriers. This is necessary since we may also be
3852 // copying unboxed doubles. 3874 // copying unboxed doubles.
3853 Node* field = 3875 Node* field =
3854 assembler->LoadObjectField(boilerplate, i, MachineType::IntPtr()); 3876 assembler->Load(MachineType::IntPtr(), boilerplate, offset.value());
3855 assembler->StoreObjectFieldNoWriteBarrier( 3877 assembler->StoreNoWriteBarrier(MachineType::PointerRepresentation(), copy,
3856 copy, i, field, MachineType::PointerRepresentation()); 3878 offset.value(), field);
3879 assembler->Goto(&loop_check);
3880 }
3881 assembler->Bind(&loop_check);
3882 {
3883 offset.Bind(assembler->IntPtrAdd(offset.value(),
3884 assembler->IntPtrConstant(kPointerSize)));
3885 assembler->GotoUnless(
3886 assembler->IntPtrGreaterThanOrEqual(offset.value(), end_offset),
3887 &loop_body);
3857 } 3888 }
3858 3889
3859 if (FLAG_allocation_site_pretenuring) { 3890 if (FLAG_allocation_site_pretenuring) {
3860 Node* memento = assembler->InnerAllocate(copy, object_size); 3891 Node* memento = assembler->InnerAllocate(copy, object_size);
3861 assembler->StoreObjectFieldNoWriteBarrier( 3892 assembler->StoreObjectFieldNoWriteBarrier(
3862 memento, HeapObject::kMapOffset, 3893 memento, HeapObject::kMapOffset,
3863 assembler->LoadRoot(Heap::kAllocationMementoMapRootIndex)); 3894 assembler->LoadRoot(Heap::kAllocationMementoMapRootIndex));
3864 assembler->StoreObjectFieldNoWriteBarrier( 3895 assembler->StoreObjectFieldNoWriteBarrier(
3865 memento, AllocationMemento::kAllocationSiteOffset, allocation_site); 3896 memento, AllocationMemento::kAllocationSiteOffset, allocation_site);
3866 Node* memento_create_count = assembler->LoadObjectField( 3897 Node* memento_create_count = assembler->LoadObjectField(
3867 allocation_site, AllocationSite::kPretenureCreateCountOffset); 3898 allocation_site, AllocationSite::kPretenureCreateCountOffset);
3868 memento_create_count = assembler->SmiAdd( 3899 memento_create_count = assembler->SmiAdd(
3869 memento_create_count, assembler->SmiConstant(Smi::FromInt(1))); 3900 memento_create_count, assembler->SmiConstant(Smi::FromInt(1)));
3870 assembler->StoreObjectFieldNoWriteBarrier( 3901 assembler->StoreObjectFieldNoWriteBarrier(
3871 allocation_site, AllocationSite::kPretenureCreateCountOffset, 3902 allocation_site, AllocationSite::kPretenureCreateCountOffset,
3872 memento_create_count); 3903 memento_create_count);
3873 } 3904 }
3874 3905
3875 // TODO(verwaest): Allocate and fill in double boxes. 3906 // TODO(verwaest): Allocate and fill in double boxes.
3907 return copy;
3908 }
3909
3910 void FastCloneShallowObjectStub::GenerateAssembly(
3911 CodeStubAssembler* assembler) const {
3912 typedef CodeStubAssembler::Label Label;
3913 typedef compiler::Node Node;
3914 Label call_runtime(assembler);
3915 Node* closure = assembler->Parameter(0);
3916 Node* literals_index = assembler->Parameter(1);
3917
3918 Node* properties_count =
3919 assembler->IntPtrConstant(PropertiesCount(this->length()));
3920 Node* copy = GenerateFastPath(assembler, &call_runtime, closure,
3921 literals_index, properties_count);
3876 assembler->Return(copy); 3922 assembler->Return(copy);
3877 3923
3878 assembler->Bind(&call_runtime); 3924 assembler->Bind(&call_runtime);
3879 Node* constant_properties = assembler->Parameter(2); 3925 Node* constant_properties = assembler->Parameter(2);
3880 Node* flags = assembler->Parameter(3); 3926 Node* flags = assembler->Parameter(3);
3881 Node* context = assembler->Parameter(4); 3927 Node* context = assembler->Parameter(4);
3882 assembler->TailCallRuntime(Runtime::kCreateObjectLiteral, context, closure, 3928 assembler->TailCallRuntime(Runtime::kCreateObjectLiteral, context, closure,
3883 literals_index, constant_properties, flags); 3929 literals_index, constant_properties, flags);
3884 } 3930 }
3885 3931
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
4306 if (type->Is(Type::UntaggedPointer())) { 4352 if (type->Is(Type::UntaggedPointer())) {
4307 return Representation::External(); 4353 return Representation::External();
4308 } 4354 }
4309 4355
4310 DCHECK(!type->Is(Type::Untagged())); 4356 DCHECK(!type->Is(Type::Untagged()));
4311 return Representation::Tagged(); 4357 return Representation::Tagged();
4312 } 4358 }
4313 4359
4314 } // namespace internal 4360 } // namespace internal
4315 } // namespace v8 4361 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698