OLD | NEW |
---|---|
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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-stub-assembler.h" | 5 #include "src/code-stub-assembler.h" |
6 #include "src/code-factory.h" | 6 #include "src/code-factory.h" |
7 #include "src/frames-inl.h" | 7 #include "src/frames-inl.h" |
8 #include "src/frames.h" | 8 #include "src/frames.h" |
9 #include "src/ic/handler-configuration.h" | 9 #include "src/ic/handler-configuration.h" |
10 #include "src/ic/stub-cache.h" | 10 #include "src/ic/stub-cache.h" |
(...skipping 4432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4443 TailCallStub(descriptor, handler, p->context, receiver, fake_name, p->slot, | 4443 TailCallStub(descriptor, handler, p->context, receiver, fake_name, p->slot, |
4444 p->vector); | 4444 p->vector); |
4445 } | 4445 } |
4446 Bind(&miss); | 4446 Bind(&miss); |
4447 { | 4447 { |
4448 TailCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->slot, | 4448 TailCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->slot, |
4449 p->vector); | 4449 p->vector); |
4450 } | 4450 } |
4451 } | 4451 } |
4452 | 4452 |
4453 void CodeStubAssembler::ExtendPropertiesBackingStore(compiler::Node* object) { | |
4454 Node* properties = LoadProperties(object); | |
4455 Node* length = LoadFixedArrayBaseLength(properties); | |
4456 | |
4457 ParameterMode mode = OptimalParameterMode(); | |
4458 length = UntagParameter(length, mode); | |
4459 | |
4460 Node* delta = IntPtrOrSmiConstant(JSObject::kFieldsAdded, mode); | |
4461 Node* new_capacity = IntPtrAdd(length, delta); | |
4462 | |
4463 // Grow properties array. | |
4464 ElementsKind kind = FAST_ELEMENTS; | |
4465 DCHECK(kMaxNumberOfDescriptors + JSObject::kFieldsAdded < | |
4466 FixedArrayBase::GetMaxLengthForNewSpaceAllocation(kind)); | |
4467 // The size of a new properties backing store is guaranteed to be small | |
4468 // enough that the new backing store will be allocated in new space. | |
4469 Assert(UintPtrLessThan(new_capacity, IntPtrConstant(kMaxNumberOfDescriptors + | |
4470 JSObject::kFieldsAdded))); | |
4471 | |
4472 Node* new_properties = AllocateFixedArray(kind, new_capacity, mode); | |
4473 | |
4474 FillFixedArrayWithValue(kind, new_properties, length, new_capacity, | |
4475 Heap::kUndefinedValueRootIndex, mode); | |
4476 | |
4477 // |new_properties| is guaranteed to be in new space, so we can skip | |
4478 // the write barrier. | |
4479 CopyFixedArrayElements(kind, properties, new_properties, length, | |
4480 SKIP_WRITE_BARRIER, mode); | |
4481 | |
4482 StoreObjectField(object, JSObject::kPropertiesOffset, new_properties); | |
4483 } | |
4484 | |
4453 Node* CodeStubAssembler::PrepareValueForWrite(Node* value, | 4485 Node* CodeStubAssembler::PrepareValueForWrite(Node* value, |
4454 Representation representation, | 4486 Representation representation, |
4455 Label* bailout) { | 4487 Label* bailout) { |
4456 if (representation.IsDouble()) { | 4488 if (representation.IsDouble()) { |
4457 Variable var_value(this, MachineRepresentation::kFloat64); | 4489 Variable var_value(this, MachineRepresentation::kFloat64); |
4458 Label if_smi(this), if_heap_object(this), done(this); | 4490 Label if_smi(this), if_heap_object(this), done(this); |
4459 Branch(WordIsSmi(value), &if_smi, &if_heap_object); | 4491 Branch(WordIsSmi(value), &if_smi, &if_heap_object); |
4460 Bind(&if_smi); | 4492 Bind(&if_smi); |
4461 { | 4493 { |
4462 var_value.Bind(SmiToFloat64(value)); | 4494 var_value.Bind(SmiToFloat64(value)); |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4875 length, capacity, mode, bailout); | 4907 length, capacity, mode, bailout); |
4876 | 4908 |
4877 new_elements_var.Bind(new_elements); | 4909 new_elements_var.Bind(new_elements); |
4878 Goto(&done); | 4910 Goto(&done); |
4879 } | 4911 } |
4880 | 4912 |
4881 Bind(&done); | 4913 Bind(&done); |
4882 return new_elements_var.value(); | 4914 return new_elements_var.value(); |
4883 } | 4915 } |
4884 | 4916 |
4917 void CodeStubAssembler::TransitionElementsKind( | |
4918 compiler::Node* object, compiler::Node* map, ElementsKind from_kind, | |
4919 ElementsKind to_kind, bool is_jsarray, Label* bailout) { | |
4920 DCHECK(!IsFastHoleyElementsKind(from_kind) || | |
4921 IsFastHoleyElementsKind(to_kind)); | |
4922 if (AllocationSite::GetMode(from_kind, to_kind) == TRACK_ALLOCATION_SITE) { | |
4923 TrapAllocationMemento(object, bailout); | |
4924 } | |
4925 | |
4926 if (!IsSimpleMapChangeTransition(from_kind, to_kind)) { | |
4927 Comment("Not simple map change transition"); | |
mvstanton
2016/09/16 13:24:06
nit: "non-simple" might be better.
Igor Sheludko
2016/09/16 13:56:10
Done.
| |
4928 Node* elements = LoadElements(object); | |
4929 | |
4930 Node* empty_fixed_array = | |
4931 HeapConstant(isolate()->factory()->empty_fixed_array()); | |
4932 | |
4933 Label done(this); | |
4934 GotoIf(WordEqual(elements, empty_fixed_array), &done); | |
4935 | |
4936 // TODO(ishell): Use OptimalParameterMode(). | |
4937 ParameterMode mode = INTPTR_PARAMETERS; | |
4938 Node* elements_length = SmiUntag(LoadFixedArrayBaseLength(elements)); | |
4939 Node* array_length = | |
4940 is_jsarray ? SmiUntag(LoadObjectField(object, JSArray::kLengthOffset)) | |
4941 : elements_length; | |
4942 | |
4943 GrowElementsCapacity(object, elements, from_kind, to_kind, array_length, | |
4944 elements_length, mode, bailout); | |
4945 Goto(&done); | |
4946 Bind(&done); | |
4947 } | |
4948 | |
4949 StoreObjectField(object, JSObject::kMapOffset, map); | |
4950 } | |
4951 | |
4952 void CodeStubAssembler::TrapAllocationMemento(Node* object, | |
4953 Label* memento_found) { | |
4954 Comment("[ TrapAllocationMemento"); | |
4955 Label no_memento_found(this); | |
4956 Label top_check(this), map_check(this); | |
4957 | |
4958 Node* new_space_top_address = ExternalConstant( | |
4959 ExternalReference::new_space_allocation_top_address(isolate())); | |
4960 const int kMementoMapOffset = JSArray::kSize - kHeapObjectTag; | |
4961 const int kMementoEndOffset = kMementoMapOffset + AllocationMemento::kSize; | |
4962 | |
4963 // Bail out if the object is not in new space. | |
4964 Node* object_page = PageFromAddress(object); | |
4965 { | |
4966 const int mask = | |
4967 (1 << MemoryChunk::IN_FROM_SPACE) | (1 << MemoryChunk::IN_TO_SPACE); | |
4968 Node* page_flags = Load(MachineType::IntPtr(), object_page); | |
4969 GotoIf( | |
4970 WordEqual(WordAnd(page_flags, IntPtrConstant(mask)), IntPtrConstant(0)), | |
4971 &no_memento_found); | |
4972 } | |
4973 | |
4974 Node* memento_end = IntPtrAdd(object, IntPtrConstant(kMementoEndOffset)); | |
4975 Node* memento_end_page = PageFromAddress(memento_end); | |
4976 | |
4977 Node* new_space_top = Load(MachineType::Pointer(), new_space_top_address); | |
4978 Node* new_space_top_page = PageFromAddress(new_space_top); | |
4979 | |
4980 // If the object is in new space, we need to check whether it is and | |
Jakob Kummerow
2016/09/21 22:53:35
nit: this sentence is a little garbled.
| |
4981 // respective potential memento object on the same page as the current top. | |
4982 GotoIf(WordEqual(memento_end_page, new_space_top_page), &top_check); | |
4983 | |
4984 // The object is on a different page than allocation top. Bail out if the | |
4985 // object sits on the page boundary as no memento can follow and we cannot | |
4986 // touch the memory following it. | |
4987 Branch(WordEqual(object_page, memento_end_page), &map_check, | |
Jakob Kummerow
2016/09/21 22:53:35
This is slightly imprecise, right? |memento_end| p
| |
4988 &no_memento_found); | |
4989 | |
4990 // If top is on the same page as the current object, we need to check whether | |
4991 // we are below top. | |
4992 Bind(&top_check); | |
4993 { | |
4994 Branch(UintPtrGreaterThan(memento_end, new_space_top), &no_memento_found, | |
4995 &map_check); | |
4996 } | |
4997 | |
4998 // Memento map check. | |
4999 Bind(&map_check); | |
5000 { | |
5001 Node* memento_map = LoadObjectField(object, kMementoMapOffset); | |
5002 Branch( | |
5003 WordEqual(memento_map, LoadRoot(Heap::kAllocationMementoMapRootIndex)), | |
5004 memento_found, &no_memento_found); | |
5005 } | |
5006 Bind(&no_memento_found); | |
5007 Comment("] TrapAllocationMemento"); | |
5008 } | |
5009 | |
5010 Node* CodeStubAssembler::PageFromAddress(Node* address) { | |
5011 return WordAnd(address, IntPtrConstant(~Page::kPageAlignmentMask)); | |
5012 } | |
5013 | |
4885 Node* CodeStubAssembler::EnumLength(Node* map) { | 5014 Node* CodeStubAssembler::EnumLength(Node* map) { |
4886 Node* bitfield_3 = LoadMapBitField3(map); | 5015 Node* bitfield_3 = LoadMapBitField3(map); |
4887 Node* enum_length = BitFieldDecode<Map::EnumLengthBits>(bitfield_3); | 5016 Node* enum_length = BitFieldDecode<Map::EnumLengthBits>(bitfield_3); |
4888 return SmiTag(enum_length); | 5017 return SmiTag(enum_length); |
4889 } | 5018 } |
4890 | 5019 |
4891 void CodeStubAssembler::CheckEnumCache(Node* receiver, Label* use_cache, | 5020 void CodeStubAssembler::CheckEnumCache(Node* receiver, Label* use_cache, |
4892 Label* use_runtime) { | 5021 Label* use_runtime) { |
4893 Variable current_js_object(this, MachineRepresentation::kTagged); | 5022 Variable current_js_object(this, MachineRepresentation::kTagged); |
4894 current_js_object.Bind(receiver); | 5023 current_js_object.Bind(receiver); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5008 Heap::kTheHoleValueRootIndex); | 5137 Heap::kTheHoleValueRootIndex); |
5009 | 5138 |
5010 // Store the WeakCell in the feedback vector. | 5139 // Store the WeakCell in the feedback vector. |
5011 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, | 5140 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, |
5012 CodeStubAssembler::SMI_PARAMETERS); | 5141 CodeStubAssembler::SMI_PARAMETERS); |
5013 return cell; | 5142 return cell; |
5014 } | 5143 } |
5015 | 5144 |
5016 } // namespace internal | 5145 } // namespace internal |
5017 } // namespace v8 | 5146 } // namespace v8 |
OLD | NEW |