Chromium Code Reviews| Index: src/code-stub-assembler.cc |
| diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc |
| index 7ed1fbfda56e9725b27bca24ec5e820a524bee1a..62df240cb22b1b4be92b3a7d38376976562e72da 100644 |
| --- a/src/code-stub-assembler.cc |
| +++ b/src/code-stub-assembler.cc |
| @@ -1,7 +1,6 @@ |
| // Copyright 2016 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| - |
| #include "src/code-stub-assembler.h" |
| #include "src/code-factory.h" |
| #include "src/frames-inl.h" |
| @@ -586,6 +585,24 @@ void CodeStubAssembler::BranchIfPrototypesHaveNoElements( |
| } |
| } |
| +void CodeStubAssembler::BranchIfJSReceiver(Node* object, Label* if_true, |
| + Label* if_false) { |
| + GotoIf(TaggedIsSmi(object), if_false); |
| + STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
| + Branch(Int32GreaterThanOrEqual(LoadInstanceType(object), |
| + Int32Constant(FIRST_JS_RECEIVER_TYPE)), |
| + if_true, if_false); |
| +} |
| + |
| +void CodeStubAssembler::BranchIfJSObject(Node* object, Label* if_true, |
| + Label* if_false) { |
| + GotoIf(TaggedIsSmi(object), if_false); |
| + STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); |
| + Branch(Int32GreaterThanOrEqual(LoadInstanceType(object), |
| + Int32Constant(FIRST_JS_OBJECT_TYPE)), |
| + if_true, if_false); |
| +} |
| + |
| void CodeStubAssembler::BranchIfFastJSArray(Node* object, Node* context, |
| Label* if_true, Label* if_false) { |
| // Bailout if receiver is a Smi. |
| @@ -911,10 +928,14 @@ Node* CodeStubAssembler::LoadInstanceType(Node* object) { |
| return LoadMapInstanceType(LoadMap(object)); |
| } |
| +Node* CodeStubAssembler::HasInstanceType(Node* object, |
| + InstanceType instance_type) { |
| + return Word32Equal(LoadInstanceType(object), Int32Constant(instance_type)); |
| +} |
| + |
| void CodeStubAssembler::AssertInstanceType(Node* object, |
| InstanceType instance_type) { |
| - CSA_ASSERT( |
| - Word32Equal(LoadInstanceType(object), Int32Constant(instance_type))); |
| + CSA_ASSERT(HasInstanceType(object, instance_type)); |
| } |
| Node* CodeStubAssembler::LoadProperties(Node* object) { |
| @@ -962,10 +983,25 @@ Node* CodeStubAssembler::LoadMapDescriptors(Node* map) { |
| return LoadObjectField(map, Map::kDescriptorsOffset); |
| } |
| +Node* CodeStubAssembler::LoadMapNumberOfOwnDescriptors(Node* map) { |
|
Igor Sheludko
2016/10/18 12:33:21
Semi-useful. Usually we load this number after a f
Camillo Bruni
2016/10/18 14:06:00
removing it.
|
| + return BitFieldDecodeWord<Map::NumberOfOwnDescriptorsBits>( |
| + LoadMapBitField3(map)); |
| +} |
| + |
| Node* CodeStubAssembler::LoadMapPrototype(Node* map) { |
| return LoadObjectField(map, Map::kPrototypeOffset); |
| } |
| +Node* CodeStubAssembler::LoadMapPrototypeInfo(Node* map, |
| + Label* if_no_proto_info) { |
| + Node* prototype_info = |
| + LoadObjectField(map, Map::kTransitionsOrPrototypeInfoOffset); |
| + GotoIf(TaggedIsSmi(prototype_info), if_no_proto_info); |
| + GotoUnless(HasInstanceType(prototype_info, PROTOTYPE_INFO_TYPE), |
|
Igor Sheludko
2016/10/18 12:33:21
Map check is better here.
Camillo Bruni
2016/10/18 14:06:00
done.
|
| + if_no_proto_info); |
| + return prototype_info; |
| +} |
| + |
| Node* CodeStubAssembler::LoadMapInstanceSize(Node* map) { |
| return ChangeUint32ToWord( |
| LoadObjectField(map, Map::kInstanceSizeOffset, MachineType::Uint8())); |
| @@ -1011,6 +1047,25 @@ Node* CodeStubAssembler::LoadMapConstructor(Node* map) { |
| return result.value(); |
| } |
| +Node* CodeStubAssembler::IsFastMap(Node* map) { |
|
Igor Sheludko
2016/10/18 12:33:21
Semi-useful. Same a above.
Camillo Bruni
2016/10/18 14:06:00
agreed, removed it.
|
| + Node* bit_field3 = LoadMapBitField3(map); |
| + return BitFieldDecode<Map::DictionaryMap>(bit_field3); |
| +} |
| + |
| +Node* CodeStubAssembler::IsSpecialReceiverMap(Node* map) { |
| + Node* bit_field = LoadMapBitField(map); |
| + Node* mask = Int32Constant(1 << Map::kHasNamedInterceptor | |
| + 1 << Map::kIsAccessCheckNeeded); |
| + Assert(Word32Equal(Word32And(bit_field, mask), Int32Constant(0))); |
| + return IsSpecialReceiverInstanceType(LoadMapInstanceType(map)); |
| +} |
| + |
| +Node* CodeStubAssembler::IsSpecialReceiverInstanceType(Node* instance_type) { |
| + STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); |
| + return Int32LessThanOrEqual(instance_type, |
| + Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)); |
| +} |
| + |
| Node* CodeStubAssembler::LoadNameHashField(Node* name) { |
| return LoadObjectField(name, Name::kHashFieldOffset, MachineType::Uint32()); |
| } |
| @@ -1439,6 +1494,72 @@ Node* CodeStubAssembler::AllocateRegExpResult(Node* context, Node* length, |
| return result; |
| } |
| +Node* CodeStubAssembler::AllocateJSObjectFromMap(Node* map, Node* properties, |
| + Node* elements) { |
| + Node* size = |
| + IntPtrMul(LoadMapInstanceSize(map), IntPtrConstant(kPointerSize)); |
| + Node* object = Allocate(size); |
| + StoreMapNoWriteBarrier(object, map); |
| + InitializeJSObjectFromMap(object, map, size, properties, elements); |
| + return object; |
| +} |
| + |
| +void CodeStubAssembler::InitializeJSObjectFromMap(Node* object, Node* map, |
| + Node* size, Node* properties, |
| + Node* elements) { |
| + if (properties == nullptr) { |
| + StoreObjectFieldRoot(object, JSObject::kPropertiesOffset, |
| + Heap::kEmptyFixedArrayRootIndex); |
| + } else { |
| + StoreObjectFieldNoWriteBarrier(object, JSObject::kPropertiesOffset, |
|
Igor Sheludko
2016/10/18 12:33:21
Please add a comment about why is it possible to s
Camillo Bruni
2016/10/18 14:06:00
done, added semi-assertion in AllocateJSObjectFrom
|
| + properties); |
| + } |
| + if (elements == nullptr) { |
| + StoreObjectFieldRoot(object, JSObject::kElementsOffset, |
| + Heap::kEmptyFixedArrayRootIndex); |
| + } else { |
| + StoreObjectFieldNoWriteBarrier(object, JSObject::kElementsOffset, elements); |
| + } |
| + InitializeJSObjectBody(object, map, size, JSObject::kHeaderSize); |
| +} |
| + |
| +void CodeStubAssembler::InitializeJSObjectBody(Node* object, Node* map, |
| + Node* size, int start_offset) { |
| + // TODO(cbruni): activate in-object slack tracking machinery. |
| + Comment("InitializeJSObjectBody"); |
| + Node* filler = LoadRoot(Heap::kUndefinedValueRootIndex); |
| + Node* start_address = IntPtrAdd(object, IntPtrConstant(start_offset)); |
| + Node* end_address = IntPtrAdd(object, size); |
| + StoreFieldsNoWriteBarrier(start_address, end_address, filler); |
| +} |
| + |
| +void CodeStubAssembler::StoreFieldsNoWriteBarrier(Node* start_address, |
| + Node* end_address, |
| + Node* value) { |
| + Comment("StoreFieldsNoWriteBarrier"); |
|
Igor Sheludko
2016/10/18 12:33:21
Consider using BuildFastLoop().
Camillo Bruni
2016/10/18 14:06:00
done.
|
| + Variable current(this, MachineRepresentation::kTagged); |
|
Igor Sheludko
2016/10/18 12:33:22
Why is it kTagged? I think it should be PointerRep
Camillo Bruni
2016/10/18 14:06:00
done.
|
| + Label decrement(this, ¤t), done(this); |
| + |
| + start_address = IntPtrSub(start_address, IntPtrConstant(1)); |
|
Igor Sheludko
2016/10/18 12:33:21
I think it would be better to "untag" it in the ca
|
| + end_address = IntPtrSub(end_address, IntPtrConstant(1)); |
|
Igor Sheludko
2016/10/18 12:33:21
And thus this would not be necessary.
Camillo Bruni
2016/10/18 14:06:00
done.
|
| + Assert(IsWordAligned(start_address)); |
| + Assert(IsWordAligned(end_address)); |
| + |
| + current.Bind(end_address); |
| + Branch(WordEqual(current.value(), start_address), &done, &decrement); |
| + Bind(&decrement); |
| + { |
| + current.Bind(IntPtrSub(current.value(), IntPtrConstant(kPointerSize))); |
| + |
| + StoreNoWriteBarrier(MachineType::PointerRepresentation(), current.value(), |
| + value); |
| + |
| + Branch(WordEqual(current.value(), start_address), &done, &decrement); |
| + } |
| + |
| + Bind(&done); |
| +} |
| + |
| Node* CodeStubAssembler::AllocateUninitializedJSArrayWithoutElements( |
| ElementsKind kind, Node* array_map, Node* length, Node* allocation_site) { |
| Comment("begin allocation of JSArray without elements"); |