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

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: Add todo 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
« no previous file with comments | « src/code-stubs.h ('k') | src/compiler/bytecode-graph-builder.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 3729 matching lines...) Expand 10 before | Expand all | Expand 10 after
3740 &if_keyisinvalid); 3740 &if_keyisinvalid);
3741 assembler->Bind(&if_keyispositivesmi); 3741 assembler->Bind(&if_keyispositivesmi);
3742 assembler->TailCallRuntime(Runtime::kLoadElementWithInterceptor, context, 3742 assembler->TailCallRuntime(Runtime::kLoadElementWithInterceptor, context,
3743 receiver, key); 3743 receiver, key);
3744 3744
3745 assembler->Bind(&if_keyisinvalid); 3745 assembler->Bind(&if_keyisinvalid);
3746 assembler->TailCallRuntime(Runtime::kKeyedLoadIC_Miss, context, receiver, key, 3746 assembler->TailCallRuntime(Runtime::kKeyedLoadIC_Miss, context, receiver, key,
3747 slot, vector); 3747 slot, vector);
3748 } 3748 }
3749 3749
3750 void FastCloneShallowObjectStub::GenerateAssembly( 3750 // static
3751 CodeStubAssembler* assembler) const { 3751 bool FastCloneShallowObjectStub::IsSupported(ObjectLiteral* expr) {
3752 typedef CodeStubAssembler::Label Label; 3752 // FastCloneShallowObjectStub doesn't copy elements, and object literals don't
3753 // support copy-on-write (COW) elements for now.
3754 // TODO(mvstanton): make object literals support COW elements.
3755 return expr->fast_elements() && expr->has_shallow_properties() &&
3756 expr->properties_count() <= kMaximumClonedProperties;
3757 }
3758
3759 // static
3760 int FastCloneShallowObjectStub::PropertiesCount(int literal_length) {
3761 // This heuristic of setting empty literals to have
3762 // kInitialGlobalObjectUnusedPropertiesCount must remain in-sync with the
3763 // runtime.
3764 // TODO(verwaest): Unify this with the heuristic in the runtime.
3765 return literal_length == 0
3766 ? JSObject::kInitialGlobalObjectUnusedPropertiesCount
3767 : literal_length;
3768 }
3769
3770 // static
3771 compiler::Node* FastCloneShallowObjectStub::GenerateFastPath(
3772 CodeStubAssembler* assembler, compiler::CodeAssembler::Label* call_runtime,
3773 compiler::Node* closure, compiler::Node* literals_index,
3774 compiler::Node* properties_count) {
3753 typedef compiler::Node Node; 3775 typedef compiler::Node Node;
3754 Label call_runtime(assembler); 3776 typedef compiler::CodeAssembler::Label Label;
3755 Node* closure = assembler->Parameter(0); 3777 typedef compiler::CodeAssembler::Variable Variable;
3756 Node* literals_index = assembler->Parameter(1);
3757 3778
3758 Node* undefined = assembler->UndefinedConstant(); 3779 Node* undefined = assembler->UndefinedConstant();
3759 Node* literals_array = 3780 Node* literals_array =
3760 assembler->LoadObjectField(closure, JSFunction::kLiteralsOffset); 3781 assembler->LoadObjectField(closure, JSFunction::kLiteralsOffset);
3761 Node* allocation_site = assembler->LoadFixedArrayElementSmiIndex( 3782 Node* allocation_site = assembler->LoadFixedArrayElementSmiIndex(
3762 literals_array, literals_index, 3783 literals_array, literals_index,
3763 LiteralsArray::kFirstLiteralIndex * kPointerSize); 3784 LiteralsArray::kFirstLiteralIndex * kPointerSize);
3764 assembler->GotoIf(assembler->WordEqual(allocation_site, undefined), 3785 assembler->GotoIf(assembler->WordEqual(allocation_site, undefined),
3765 &call_runtime); 3786 call_runtime);
3766 3787
3788 // Calculate the object and allocation size based on the properties count.
3789 Node* object_size = assembler->IntPtrAdd(
3790 assembler->WordShl(properties_count, kPointerSizeLog2),
3791 assembler->IntPtrConstant(JSObject::kHeaderSize));
3792 Node* allocation_size = object_size;
3793 if (FLAG_allocation_site_pretenuring) {
3794 allocation_size = assembler->IntPtrAdd(
3795 object_size, assembler->IntPtrConstant(AllocationMemento::kSize));
3796 }
3767 Node* boilerplate = assembler->LoadObjectField( 3797 Node* boilerplate = assembler->LoadObjectField(
3768 allocation_site, AllocationSite::kTransitionInfoOffset); 3798 allocation_site, AllocationSite::kTransitionInfoOffset);
3769
3770 int length = this->length();
3771 if (length == 0) {
3772 length = JSObject::kInitialGlobalObjectUnusedPropertiesCount;
3773 }
3774 int allocation_size = JSObject::kHeaderSize + length * kPointerSize;
3775 int object_size = allocation_size;
3776 if (FLAG_allocation_site_pretenuring) {
3777 allocation_size += AllocationMemento::kSize;
3778 }
3779
3780 Node* boilerplate_map = assembler->LoadMap(boilerplate); 3799 Node* boilerplate_map = assembler->LoadMap(boilerplate);
3781 Node* instance_size = assembler->LoadMapInstanceSize(boilerplate_map); 3800 Node* instance_size = assembler->LoadMapInstanceSize(boilerplate_map);
3782 Node* size_in_words = 3801 Node* size_in_words = assembler->WordShr(object_size, kPointerSizeLog2);
3783 assembler->Int32Constant(object_size >> kPointerSizeLog2);
3784 assembler->GotoUnless(assembler->Word32Equal(instance_size, size_in_words), 3802 assembler->GotoUnless(assembler->Word32Equal(instance_size, size_in_words),
3785 &call_runtime); 3803 call_runtime);
3786 3804
3787 Node* copy = assembler->Allocate(allocation_size); 3805 Node* copy = assembler->Allocate(allocation_size);
3788 3806
3789 for (int i = 0; i < object_size; i += kPointerSize) { 3807 // Copy boilerplate elements.
3808 Variable offset(assembler, MachineType::PointerRepresentation());
3809 offset.Bind(assembler->IntPtrConstant(-kHeapObjectTag));
3810 Node* end_offset = assembler->IntPtrAdd(object_size, offset.value());
3811 Label loop_body(assembler, &offset), loop_check(assembler, &offset);
3812 // We should always have an object size greater than zero.
3813 assembler->Goto(&loop_body);
3814 assembler->Bind(&loop_body);
3815 {
3790 // The Allocate above guarantees that the copy lies in new space. This 3816 // The Allocate above guarantees that the copy lies in new space. This
3791 // allows us to skip write barriers. This is necessary since we may also be 3817 // allows us to skip write barriers. This is necessary since we may also be
3792 // copying unboxed doubles. 3818 // copying unboxed doubles.
3793 Node* field = 3819 Node* field =
3794 assembler->LoadObjectField(boilerplate, i, MachineType::IntPtr()); 3820 assembler->Load(MachineType::IntPtr(), boilerplate, offset.value());
3795 assembler->StoreObjectFieldNoWriteBarrier( 3821 assembler->StoreNoWriteBarrier(MachineType::PointerRepresentation(), copy,
3796 copy, i, field, MachineType::PointerRepresentation()); 3822 offset.value(), field);
3823 assembler->Goto(&loop_check);
3824 }
3825 assembler->Bind(&loop_check);
3826 {
3827 offset.Bind(assembler->IntPtrAdd(offset.value(),
3828 assembler->IntPtrConstant(kPointerSize)));
3829 assembler->GotoUnless(
3830 assembler->IntPtrGreaterThanOrEqual(offset.value(), end_offset),
3831 &loop_body);
3797 } 3832 }
3798 3833
3799 if (FLAG_allocation_site_pretenuring) { 3834 if (FLAG_allocation_site_pretenuring) {
3800 Node* memento = assembler->InnerAllocate(copy, object_size); 3835 Node* memento = assembler->InnerAllocate(copy, object_size);
3801 assembler->StoreObjectFieldNoWriteBarrier( 3836 assembler->StoreObjectFieldNoWriteBarrier(
3802 memento, HeapObject::kMapOffset, 3837 memento, HeapObject::kMapOffset,
3803 assembler->LoadRoot(Heap::kAllocationMementoMapRootIndex)); 3838 assembler->LoadRoot(Heap::kAllocationMementoMapRootIndex));
3804 assembler->StoreObjectFieldNoWriteBarrier( 3839 assembler->StoreObjectFieldNoWriteBarrier(
3805 memento, AllocationMemento::kAllocationSiteOffset, allocation_site); 3840 memento, AllocationMemento::kAllocationSiteOffset, allocation_site);
3806 Node* memento_create_count = assembler->LoadObjectField( 3841 Node* memento_create_count = assembler->LoadObjectField(
3807 allocation_site, AllocationSite::kPretenureCreateCountOffset); 3842 allocation_site, AllocationSite::kPretenureCreateCountOffset);
3808 memento_create_count = assembler->SmiAdd( 3843 memento_create_count = assembler->SmiAdd(
3809 memento_create_count, assembler->SmiConstant(Smi::FromInt(1))); 3844 memento_create_count, assembler->SmiConstant(Smi::FromInt(1)));
3810 assembler->StoreObjectFieldNoWriteBarrier( 3845 assembler->StoreObjectFieldNoWriteBarrier(
3811 allocation_site, AllocationSite::kPretenureCreateCountOffset, 3846 allocation_site, AllocationSite::kPretenureCreateCountOffset,
3812 memento_create_count); 3847 memento_create_count);
3813 } 3848 }
3814 3849
3815 // TODO(verwaest): Allocate and fill in double boxes. 3850 // TODO(verwaest): Allocate and fill in double boxes.
3851 return copy;
3852 }
3853
3854 void FastCloneShallowObjectStub::GenerateAssembly(
3855 CodeStubAssembler* assembler) const {
3856 typedef CodeStubAssembler::Label Label;
3857 typedef compiler::Node Node;
3858 Label call_runtime(assembler);
3859 Node* closure = assembler->Parameter(0);
3860 Node* literals_index = assembler->Parameter(1);
3861
3862 Node* properties_count =
3863 assembler->IntPtrConstant(PropertiesCount(this->length()));
3864 Node* copy = GenerateFastPath(assembler, &call_runtime, closure,
3865 literals_index, properties_count);
3816 assembler->Return(copy); 3866 assembler->Return(copy);
3817 3867
3818 assembler->Bind(&call_runtime); 3868 assembler->Bind(&call_runtime);
3819 Node* constant_properties = assembler->Parameter(2); 3869 Node* constant_properties = assembler->Parameter(2);
3820 Node* flags = assembler->Parameter(3); 3870 Node* flags = assembler->Parameter(3);
3821 Node* context = assembler->Parameter(4); 3871 Node* context = assembler->Parameter(4);
3822 assembler->TailCallRuntime(Runtime::kCreateObjectLiteral, context, closure, 3872 assembler->TailCallRuntime(Runtime::kCreateObjectLiteral, context, closure,
3823 literals_index, constant_properties, flags); 3873 literals_index, constant_properties, flags);
3824 } 3874 }
3825 3875
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
4246 if (type->Is(Type::UntaggedPointer())) { 4296 if (type->Is(Type::UntaggedPointer())) {
4247 return Representation::External(); 4297 return Representation::External();
4248 } 4298 }
4249 4299
4250 DCHECK(!type->Is(Type::Untagged())); 4300 DCHECK(!type->Is(Type::Untagged()));
4251 return Representation::Tagged(); 4301 return Representation::Tagged();
4252 } 4302 }
4253 4303
4254 } // namespace internal 4304 } // namespace internal
4255 } // namespace v8 4305 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stubs.h ('k') | src/compiler/bytecode-graph-builder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698