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

Unified Diff: src/code-stub-assembler.cc

Issue 2385423005: [stubs] Implement fast TF Builtin for Object.create (Closed)
Patch Set: fix heap verification call Created 4 years, 2 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 side-by-side diff with in-line comments
Download patch
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, &current), 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");

Powered by Google App Engine
This is Rietveld 408576698