| Index: src/code-stub-assembler.cc
|
| diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc
|
| index e05067543008128445508d4bfc2d758a3999107b..4408a0d1cb1f3759e410668c2cf2f5911850e484 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"
|
| @@ -525,6 +524,11 @@ Node* CodeStubAssembler::WordIsPositiveSmi(Node* a) {
|
| IntPtrConstant(0));
|
| }
|
|
|
| +Node* CodeStubAssembler::WordIsWordAligned(Node* word) {
|
| + return WordEqual(IntPtrConstant(0),
|
| + WordAnd(word, IntPtrConstant((1 << kPointerSizeLog2) - 1)));
|
| +}
|
| +
|
| void CodeStubAssembler::BranchIfSimd128Equal(Node* lhs, Node* lhs_map,
|
| Node* rhs, Node* rhs_map,
|
| Label* if_equal,
|
| @@ -625,6 +629,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.
|
| @@ -785,6 +807,11 @@ Node* CodeStubAssembler::InnerAllocate(Node* previous, int offset) {
|
| return InnerAllocate(previous, IntPtrConstant(offset));
|
| }
|
|
|
| +Node* CodeStubAssembler::IsRegularHeapObjectSize(Node* size) {
|
| + return UintPtrLessThanOrEqual(size,
|
| + IntPtrConstant(kMaxRegularHeapObjectSize));
|
| +}
|
| +
|
| void CodeStubAssembler::BranchIfToBooleanIsTrue(Node* value, Label* if_true,
|
| Label* if_false) {
|
| Label if_valueissmi(this), if_valueisnotsmi(this), if_valueisstring(this),
|
| @@ -950,10 +977,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) {
|
| @@ -1005,6 +1036,17 @@ 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(WordEqual(LoadMap(prototype_info),
|
| + LoadRoot(Heap::kPrototypeInfoMapRootIndex)),
|
| + if_no_proto_info);
|
| + return prototype_info;
|
| +}
|
| +
|
| Node* CodeStubAssembler::LoadMapInstanceSize(Node* map) {
|
| return ChangeUint32ToWord(
|
| LoadObjectField(map, Map::kInstanceSizeOffset, MachineType::Uint8()));
|
| @@ -1050,6 +1092,20 @@ Node* CodeStubAssembler::LoadMapConstructor(Node* map) {
|
| return result.value();
|
| }
|
|
|
| +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());
|
| }
|
| @@ -1604,6 +1660,66 @@ 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));
|
| + CSA_ASSERT(IsRegularHeapObjectSize(size));
|
| + 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) {
|
| + // This helper assumes that the object is in new-space, as guarded by the
|
| + // check in AllocatedJSObjectFromMap.
|
| + if (properties == nullptr) {
|
| + StoreObjectFieldRoot(object, JSObject::kPropertiesOffset,
|
| + Heap::kEmptyFixedArrayRootIndex);
|
| + } else {
|
| + StoreObjectFieldNoWriteBarrier(object, JSObject::kPropertiesOffset,
|
| + 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);
|
| + // Calculate the untagged field addresses.
|
| + Node* start_address =
|
| + IntPtrAdd(object, IntPtrConstant(start_offset - kHeapObjectTag));
|
| + Node* end_address =
|
| + IntPtrSub(IntPtrAdd(object, size), IntPtrConstant(kHeapObjectTag));
|
| + StoreFieldsNoWriteBarrier(start_address, end_address, filler);
|
| +}
|
| +
|
| +void CodeStubAssembler::StoreFieldsNoWriteBarrier(Node* start_address,
|
| + Node* end_address,
|
| + Node* value) {
|
| + Comment("StoreFieldsNoWriteBarrier");
|
| + CSA_ASSERT(WordIsWordAligned(start_address));
|
| + CSA_ASSERT(WordIsWordAligned(end_address));
|
| + BuildFastLoop(MachineType::PointerRepresentation(), start_address,
|
| + end_address,
|
| + [value](CodeStubAssembler* a, Node* current) {
|
| + a->StoreNoWriteBarrier(MachineType::PointerRepresentation(),
|
| + current, value);
|
| + },
|
| + kPointerSize, IndexAdvanceMode::kPost);
|
| +}
|
| +
|
| Node* CodeStubAssembler::AllocateUninitializedJSArrayWithoutElements(
|
| ElementsKind kind, Node* array_map, Node* length, Node* allocation_site) {
|
| Comment("begin allocation of JSArray without elements");
|
|
|