| Index: src/builtins/builtins-constructor.cc
|
| diff --git a/src/builtins/builtins-constructor.cc b/src/builtins/builtins-constructor.cc
|
| index 241c6d6458fe206b30f9f3c693e02816b46e65ee..58a6860b0c5cfa6e2f8df004e7cf7cf989bbc06e 100644
|
| --- a/src/builtins/builtins-constructor.cc
|
| +++ b/src/builtins/builtins-constructor.cc
|
| @@ -161,30 +161,57 @@ TF_BUILTIN(FastNewObject, ConstructorBuiltinsAssembler) {
|
| Node* target = Parameter(Descriptor::kTarget);
|
| Node* new_target = Parameter(Descriptor::kNewTarget);
|
|
|
| + Label call_runtime(this);
|
| +
|
| + Node* result = EmitFastNewObject(context, target, new_target, &call_runtime);
|
| + Return(result);
|
| +
|
| + Bind(&call_runtime);
|
| + TailCallRuntime(Runtime::kNewObject, context, target, new_target);
|
| +}
|
| +
|
| +Node* ConstructorBuiltinsAssembler::EmitFastNewObject(Node* context,
|
| + Node* target,
|
| + Node* new_target) {
|
| + Variable var_obj(this, MachineRepresentation::kTagged);
|
| + Label call_runtime(this), end(this);
|
| +
|
| + Node* result = EmitFastNewObject(context, target, new_target, &call_runtime);
|
| + var_obj.Bind(result);
|
| + Goto(&end);
|
| +
|
| + Bind(&call_runtime);
|
| + var_obj.Bind(CallRuntime(Runtime::kNewObject, context, target, new_target));
|
| + Goto(&end);
|
| +
|
| + Bind(&end);
|
| + return var_obj.value();
|
| +}
|
| +
|
| +Node* ConstructorBuiltinsAssembler::EmitFastNewObject(
|
| + Node* context, Node* target, Node* new_target,
|
| + CodeAssemblerLabel* call_runtime) {
|
| 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);
|
| + Label fast(this), end(this);
|
| GotoIf(HasInstanceType(new_target, JS_FUNCTION_TYPE), &fast);
|
| - Goto(&runtime);
|
| -
|
| - Bind(&runtime);
|
| - TailCallRuntime(Runtime::kNewObject, context, target, new_target);
|
| + Goto(call_runtime);
|
|
|
| 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);
|
| + GotoIf(TaggedIsSmi(initial_map), call_runtime);
|
| + GotoIf(DoesntHaveInstanceType(initial_map, MAP_TYPE), call_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);
|
| + GotoIf(WordNotEqual(target, new_target_constructor), call_runtime);
|
|
|
| Node* instance_size_words = ChangeUint32ToWord(LoadObjectField(
|
| initial_map, Map::kInstanceSizeOffset, MachineType::Uint8()));
|
| @@ -214,7 +241,7 @@ TF_BUILTIN(FastNewObject, ConstructorBuiltinsAssembler) {
|
| Comment("no slack tracking");
|
| InitializeFieldsWithRoot(object, IntPtrConstant(JSObject::kHeaderSize),
|
| instance_size, Heap::kUndefinedValueRootIndex);
|
| - Return(object);
|
| + Goto(&end);
|
| }
|
|
|
| {
|
| @@ -243,7 +270,7 @@ TF_BUILTIN(FastNewObject, ConstructorBuiltinsAssembler) {
|
| Comment("initialize undefined fields (no finalize)");
|
| InitializeFieldsWithRoot(object, IntPtrConstant(JSObject::kHeaderSize),
|
| used_size, Heap::kUndefinedValueRootIndex);
|
| - Return(object);
|
| + Goto(&end);
|
| }
|
|
|
| {
|
| @@ -265,8 +292,11 @@ TF_BUILTIN(FastNewObject, ConstructorBuiltinsAssembler) {
|
| used_size, Heap::kUndefinedValueRootIndex);
|
|
|
| CallRuntime(Runtime::kFinalizeInstanceSize, context, initial_map);
|
| - Return(object);
|
| + Goto(&end);
|
| }
|
| +
|
| + Bind(&end);
|
| + return object;
|
| }
|
|
|
| Node* ConstructorBuiltinsAssembler::EmitFastNewFunctionContext(
|
|
|