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

Unified Diff: src/builtins/builtins-constructor.cc

Issue 2606733002: [stubs] Port FastNewObjectStub to TF (Closed)
Patch Set: Review feedback Created 4 years 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
« no previous file with comments | « src/builtins/builtins.h ('k') | src/builtins/ia32/builtins-ia32.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins/builtins-constructor.cc
diff --git a/src/builtins/builtins-constructor.cc b/src/builtins/builtins-constructor.cc
index d7bf3cccdae3183cc55f26d59b731e57f0242a72..4ff9cd132cabe9468cfb25d78c4929750860bf8f 100644
--- a/src/builtins/builtins-constructor.cc
+++ b/src/builtins/builtins-constructor.cc
@@ -154,5 +154,119 @@ TF_BUILTIN(FastNewClosure, ConstructorBuiltinsAssembler) {
Return(EmitFastNewClosure(shared, context));
}
+TF_BUILTIN(FastNewObject, ConstructorBuiltinsAssembler) {
+ typedef FastNewObjectDescriptor Descriptor;
+ Node* context = Parameter(Descriptor::kContext);
+ Node* target = Parameter(Descriptor::kTarget);
+ Node* new_target = Parameter(Descriptor::kNewTarget);
+
+ CSA_ASSERT(this, HasInstanceType(target, JS_FUNCTION_TYPE));
+ CSA_ASSERT(this, IsJSReceiver(new_target));
+
+ // Verify that the new target is a JSFunction.
+ Label runtime(this), fast(this);
+ GotoIf(HasInstanceType(new_target, JS_FUNCTION_TYPE), &fast);
+ Goto(&runtime);
+
+ Bind(&runtime);
+ TailCallRuntime(Runtime::kNewObject, context, target, new_target);
+
+ Bind(&fast);
+
+ // Load the initial map and verify that it's in fact a map.
+ Node* initial_map =
+ LoadObjectField(new_target, JSFunction::kPrototypeOrInitialMapOffset);
+ GotoIf(TaggedIsSmi(initial_map), &runtime);
+ GotoIf(DoesntHaveInstanceType(initial_map, MAP_TYPE), &runtime);
+
+ // Fall back to runtime if the target differs from the new target's
+ // initial map constructor.
+ Node* new_target_constructor =
+ LoadObjectField(initial_map, Map::kConstructorOrBackPointerOffset);
+ GotoIf(WordNotEqual(target, new_target_constructor), &runtime);
+
+ Node* instance_size_words = ChangeUint32ToWord(LoadObjectField(
+ initial_map, Map::kInstanceSizeOffset, MachineType::Uint8()));
+ Node* instance_size =
+ WordShl(instance_size_words, IntPtrConstant(kPointerSizeLog2));
+
+ Node* object = Allocate(instance_size);
+ StoreMapNoWriteBarrier(object, initial_map);
+ Node* empty_array = LoadRoot(Heap::kEmptyFixedArrayRootIndex);
+ StoreObjectFieldNoWriteBarrier(object, JSObject::kPropertiesOffset,
+ empty_array);
+ StoreObjectFieldNoWriteBarrier(object, JSObject::kElementsOffset,
+ empty_array);
+
+ instance_size_words = ChangeUint32ToWord(LoadObjectField(
+ initial_map, Map::kInstanceSizeOffset, MachineType::Uint8()));
+ instance_size =
+ WordShl(instance_size_words, IntPtrConstant(kPointerSizeLog2));
+
+ // Perform in-object slack tracking if requested.
+ Node* bit_field3 = LoadMapBitField3(initial_map);
+ Label slack_tracking(this), finalize(this, Label::kDeferred), done(this);
+ GotoIf(IsSetWord32<Map::ConstructionCounter>(bit_field3), &slack_tracking);
+
+ // Initialize remaining fields.
+ {
+ Comment("no slack tracking");
+ InitializeFieldsWithRoot(object, IntPtrConstant(JSObject::kHeaderSize),
+ instance_size, Heap::kUndefinedValueRootIndex);
+ Return(object);
+ }
+
+ {
+ Bind(&slack_tracking);
+
+ // Decrease generous allocation count.
+ STATIC_ASSERT(Map::ConstructionCounter::kNext == 32);
+ Comment("update allocation count");
+ Node* new_bit_field3 = Int32Sub(
+ bit_field3, Int32Constant(1 << Map::ConstructionCounter::kShift));
+ StoreObjectFieldNoWriteBarrier(initial_map, Map::kBitField3Offset,
+ new_bit_field3,
+ MachineRepresentation::kWord32);
+ GotoIf(IsClearWord32<Map::ConstructionCounter>(new_bit_field3), &finalize);
+
+ Node* unused_fields = LoadObjectField(
+ initial_map, Map::kUnusedPropertyFieldsOffset, MachineType::Uint8());
+ Node* used_size =
+ IntPtrSub(instance_size, WordShl(ChangeUint32ToWord(unused_fields),
+ IntPtrConstant(kPointerSizeLog2)));
+
+ Comment("initialize filler fields (no finalize)");
+ InitializeFieldsWithRoot(object, used_size, instance_size,
+ Heap::kOnePointerFillerMapRootIndex);
+
+ Comment("initialize undefined fields (no finalize)");
+ InitializeFieldsWithRoot(object, IntPtrConstant(JSObject::kHeaderSize),
+ used_size, Heap::kUndefinedValueRootIndex);
+ Return(object);
+ }
+
+ {
+ // Finalize the instance size.
+ Bind(&finalize);
+
+ Node* unused_fields = LoadObjectField(
+ initial_map, Map::kUnusedPropertyFieldsOffset, MachineType::Uint8());
+ Node* used_size =
+ IntPtrSub(instance_size, WordShl(ChangeUint32ToWord(unused_fields),
+ IntPtrConstant(kPointerSizeLog2)));
+
+ Comment("initialize filler fields (finalize)");
+ InitializeFieldsWithRoot(object, used_size, instance_size,
+ Heap::kOnePointerFillerMapRootIndex);
+
+ Comment("initialize undefined fields (finalize)");
+ InitializeFieldsWithRoot(object, IntPtrConstant(JSObject::kHeaderSize),
+ used_size, Heap::kUndefinedValueRootIndex);
+
+ CallRuntime(Runtime::kFinalizeInstanceSize, context, initial_map);
+ Return(object);
+ }
+}
+
} // namespace internal
} // namespace v8
« no previous file with comments | « src/builtins/builtins.h ('k') | src/builtins/ia32/builtins-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698