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

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

Issue 2606733002: [stubs] Port FastNewObjectStub to TF (Closed)
Patch Set: Fix build 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
Index: src/builtins/builtins-internal.cc
diff --git a/src/builtins/builtins-internal.cc b/src/builtins/builtins-internal.cc
index f94ed0c16f2f6de091dfbd7da2f3077159fd3a89..984f964f84f5c879942edcd27390d957aebeb91a 100644
--- a/src/builtins/builtins-internal.cc
+++ b/src/builtins/builtins-internal.cc
@@ -309,6 +309,138 @@ void Builtins::Generate_NewRestParameterElements(
assembler.Return(assembler.EmptyFixedArrayConstant());
}
+void Builtins::Generate_FastNewObject(compiler::CodeAssemblerState* state) {
mvstanton 2016/12/29 10:24:33 TF_BUILTIN is a nice helper if you like.
+ typedef CodeStubAssembler::Label Label;
+ typedef compiler::Node Node;
+ typedef FastNewObjectDescriptor Descriptor;
+ CodeStubAssembler assembler(state);
+
+ Node* context = assembler.Parameter(Descriptor::kContext);
+ Node* target = assembler.Parameter(Descriptor::kTarget);
+ Node* new_target = assembler.Parameter(Descriptor::kNewTarget);
+
+ CSA_ASSERT(&assembler, assembler.HasInstanceType(target, JS_FUNCTION_TYPE));
+ CSA_ASSERT(&assembler, assembler.IsJSReceiver(new_target));
+
+ // Verify that the new target is a JSFunction.
+ Label runtime(&assembler), fast(&assembler);
+ assembler.GotoIf(assembler.HasInstanceType(new_target, JS_FUNCTION_TYPE),
+ &fast);
+ assembler.Goto(&runtime);
+
+ assembler.Bind(&runtime);
+ assembler.TailCallRuntime(Runtime::kNewObject, context, target, new_target);
+
+ assembler.Bind(&fast);
+
+ // Load the initial map and verify that it's in fact a map.
+ Node* initial_map = assembler.LoadObjectField(
+ new_target, JSFunction::kPrototypeOrInitialMapOffset);
+ assembler.GotoIf(assembler.TaggedIsSmi(initial_map), &runtime);
+ assembler.GotoIf(assembler.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 = assembler.LoadObjectField(
+ initial_map, Map::kConstructorOrBackPointerOffset);
+ assembler.GotoIf(assembler.WordNotEqual(target, new_target_constructor),
+ &runtime);
+
+ Node* instance_size_words =
+ assembler.ChangeUint32ToWord(assembler.LoadObjectField(
+ initial_map, Map::kInstanceSizeOffset, MachineType::Uint8()));
+ Node* instance_size = assembler.WordShl(
+ instance_size_words, assembler.IntPtrConstant(kPointerSizeLog2));
+
+ Node* object = assembler.Allocate(instance_size);
+ assembler.StoreMapNoWriteBarrier(object, initial_map);
+ Node* empty_array = assembler.LoadRoot(Heap::kEmptyFixedArrayRootIndex);
+ assembler.StoreObjectFieldNoWriteBarrier(object, JSObject::kPropertiesOffset,
+ empty_array);
+ assembler.StoreObjectFieldNoWriteBarrier(object, JSObject::kElementsOffset,
+ empty_array);
+
+ instance_size_words = assembler.ChangeUint32ToWord(assembler.LoadObjectField(
+ initial_map, Map::kInstanceSizeOffset, MachineType::Uint8()));
+ instance_size = assembler.WordShl(instance_size_words,
+ assembler.IntPtrConstant(kPointerSizeLog2));
+
+ // Perform in-object slack tracking if requested.
+ Node* bit_field3 = assembler.LoadMapBitField3(initial_map);
+ Label slack_tracking(&assembler), finalize(&assembler, Label::kDeferred),
+ done(&assembler);
+ assembler.GotoIf(assembler.IsSetWord32<Map::ConstructionCounter>(bit_field3),
+ &slack_tracking);
+
+ // Initialize remaining fields.
+ {
+ assembler.Comment("no slack tracking");
+ assembler.InitializeFieldsWithRoot(
+ object, assembler.IntPtrConstant(JSObject::kHeaderSize), instance_size,
+ Heap::kUndefinedValueRootIndex);
+ assembler.Return(object);
+ }
+
+ {
+ assembler.Bind(&slack_tracking);
+
+ // Decrease generous allocation count.
+ STATIC_ASSERT(Map::ConstructionCounter::kNext == 32);
+ assembler.Comment("update allocation count");
+ Node* new_bit_field3 = assembler.Int32Sub(
+ bit_field3,
+ assembler.Int32Constant(1 << Map::ConstructionCounter::kShift));
+ assembler.StoreObjectFieldNoWriteBarrier(initial_map, Map::kBitField3Offset,
+ new_bit_field3,
+ MachineRepresentation::kWord32);
+ assembler.GotoIf(
+ assembler.IsClearWord32<Map::ConstructionCounter>(new_bit_field3),
+ &finalize);
+
+ Node* unused_fields = assembler.LoadObjectField(
+ initial_map, Map::kUnusedPropertyFieldsOffset, MachineType::Uint8());
+ Node* used_size = assembler.IntPtrSub(
+ instance_size,
+ assembler.WordShl(assembler.ChangeUint32ToWord(unused_fields),
+ assembler.IntPtrConstant(kPointerSizeLog2)));
+
+ assembler.Comment("initialize filler fields (no finalize)");
+ assembler.InitializeFieldsWithRoot(object, used_size, instance_size,
+ Heap::kOnePointerFillerMapRootIndex);
+
+ assembler.Comment("initialize undefined fields (no finalize)");
+ assembler.InitializeFieldsWithRoot(
+ object, assembler.IntPtrConstant(JSObject::kHeaderSize), used_size,
+ Heap::kUndefinedValueRootIndex);
+ assembler.Return(object);
+ }
+
+ {
+ // Finalize the instance size.
+ assembler.Bind(&finalize);
+
+ Node* unused_fields = assembler.LoadObjectField(
+ initial_map, Map::kUnusedPropertyFieldsOffset, MachineType::Uint8());
+ Node* used_size = assembler.IntPtrSub(
+ instance_size,
+ assembler.WordShl(assembler.ChangeUint32ToWord(unused_fields),
+ assembler.IntPtrConstant(kPointerSizeLog2)));
+
+ assembler.Comment("initialize filler fields (finalize)");
+ assembler.InitializeFieldsWithRoot(object, used_size, instance_size,
+ Heap::kOnePointerFillerMapRootIndex);
+
+ assembler.Comment("initialize undefined fields (finalize)");
+ assembler.InitializeFieldsWithRoot(
+ object, assembler.IntPtrConstant(JSObject::kHeaderSize), used_size,
+ Heap::kUndefinedValueRootIndex);
+
+ assembler.CallRuntime(Runtime::kFinalizeInstanceSize, context, initial_map);
+ assembler.Return(object);
+ }
+}
+
void Builtins::Generate_ReturnReceiver(compiler::CodeAssemblerState* state) {
CodeStubAssembler assembler(state);
assembler.Return(assembler.Parameter(0));

Powered by Google App Engine
This is Rietveld 408576698