| Index: src/arm64/builtins-arm64.cc
|
| diff --git a/src/arm64/builtins-arm64.cc b/src/arm64/builtins-arm64.cc
|
| index fec5fef99af8b7559b8669ac774b69ed7f034cf0..c2dc1fa09d7d369d0ca2ba1c28f7fb1617838b16 100644
|
| --- a/src/arm64/builtins-arm64.cc
|
| +++ b/src/arm64/builtins-arm64.cc
|
| @@ -304,7 +304,6 @@ void Builtins::Generate_InOptimizationQueue(MacroAssembler* masm) {
|
|
|
| static void Generate_JSConstructStubHelper(MacroAssembler* masm,
|
| bool is_api_function,
|
| - bool count_constructions,
|
| bool create_memento) {
|
| // ----------- S t a t e -------------
|
| // -- x0 : number of arguments
|
| @@ -315,12 +314,8 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
|
| // -----------------------------------
|
|
|
| ASM_LOCATION("Builtins::Generate_JSConstructStubHelper");
|
| - // Should never count constructions for api objects.
|
| - ASSERT(!is_api_function || !count_constructions);
|
| // Should never create mementos for api functions.
|
| ASSERT(!is_api_function || !create_memento);
|
| - // Should never create mementos before slack tracking is finished.
|
| - ASSERT(!count_constructions || !create_memento);
|
|
|
| Isolate* isolate = masm->isolate();
|
|
|
| @@ -366,24 +361,28 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
|
| __ CompareInstanceType(init_map, x10, JS_FUNCTION_TYPE);
|
| __ B(eq, &rt_call);
|
|
|
| - if (count_constructions) {
|
| + Register constructon_count = x14;
|
| + if (!is_api_function) {
|
| Label allocate;
|
| + MemOperand bit_field3 =
|
| + FieldMemOperand(init_map, Map::kBitField3Offset);
|
| + // Check if slack tracking is enabled.
|
| + __ Ldr(x4, bit_field3);
|
| + __ DecodeField<Map::ConstructionCount>(constructon_count, x4);
|
| + __ Cmp(constructon_count, Operand(JSFunction::kNoSlackTracking));
|
| + __ B(eq, &allocate);
|
| // Decrease generous allocation count.
|
| - __ Ldr(x3, FieldMemOperand(constructor,
|
| - JSFunction::kSharedFunctionInfoOffset));
|
| - MemOperand constructor_count =
|
| - FieldMemOperand(x3, SharedFunctionInfo::kConstructionCountOffset);
|
| - __ Ldrb(x4, constructor_count);
|
| - __ Subs(x4, x4, 1);
|
| - __ Strb(x4, constructor_count);
|
| + __ Subs(x4, x4, Operand(1 << Map::ConstructionCount::kShift));
|
| + __ Str(x4, bit_field3);
|
| + __ Cmp(constructon_count, Operand(JSFunction::kFinishSlackTracking));
|
| __ B(ne, &allocate);
|
|
|
| // Push the constructor and map to the stack, and the constructor again
|
| // as argument to the runtime call.
|
| __ Push(constructor, init_map, constructor);
|
| - // The call will replace the stub, so the countdown is only done once.
|
| __ CallRuntime(Runtime::kHiddenFinalizeInstanceSize, 1);
|
| __ Pop(init_map, constructor);
|
| + __ Mov(constructon_count, Operand(JSFunction::kNoSlackTracking));
|
| __ Bind(&allocate);
|
| }
|
|
|
| @@ -432,7 +431,19 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
|
| Register prop_fields = x6;
|
| __ Sub(prop_fields, obj_size, JSObject::kHeaderSize / kPointerSize);
|
|
|
| - if (count_constructions) {
|
| + if (is_api_function) {
|
| + // Fill all of the property fields with undef.
|
| + __ FillFields(first_prop, prop_fields, undef);
|
| + first_prop = NoReg;
|
| + prop_fields = NoReg;
|
| + } else {
|
| + Label no_inobject_slack_tracking, done_field_initialization;
|
| +
|
| + // Check if slack tracking is enabled.
|
| + __ Cmp(constructon_count, Operand(JSFunction::kNoSlackTracking));
|
| + __ B(eq, &no_inobject_slack_tracking);
|
| + constructon_count = NoReg;
|
| +
|
| // Fill the pre-allocated fields with undef.
|
| __ FillFields(first_prop, prealloc_fields, undef);
|
|
|
| @@ -442,40 +453,43 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
|
| __ Add(first_non_prealloc, first_prop,
|
| Operand(prealloc_fields, LSL, kPointerSizeLog2));
|
|
|
| - first_prop = NoReg;
|
| -
|
| if (FLAG_debug_code) {
|
| - Register obj_end = x5;
|
| + Register obj_end = x14;
|
| __ Add(obj_end, new_obj, Operand(obj_size, LSL, kPointerSizeLog2));
|
| __ Cmp(first_non_prealloc, obj_end);
|
| __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields);
|
| }
|
|
|
| // Fill the remaining fields with one pointer filler map.
|
| - Register one_pointer_filler = x5;
|
| + Register one_pointer_filler = x14;
|
| Register non_prealloc_fields = x6;
|
| __ LoadRoot(one_pointer_filler, Heap::kOnePointerFillerMapRootIndex);
|
| __ Sub(non_prealloc_fields, prop_fields, prealloc_fields);
|
| __ FillFields(first_non_prealloc, non_prealloc_fields,
|
| one_pointer_filler);
|
| - prop_fields = NoReg;
|
| - } else if (create_memento) {
|
| - // Fill the pre-allocated fields with undef.
|
| - __ FillFields(first_prop, prop_fields, undef);
|
| - __ Add(first_prop, new_obj, Operand(obj_size, LSL, kPointerSizeLog2));
|
| - __ LoadRoot(x14, Heap::kAllocationMementoMapRootIndex);
|
| - ASSERT_EQ(0 * kPointerSize, AllocationMemento::kMapOffset);
|
| - __ Str(x14, MemOperand(first_prop, kPointerSize, PostIndex));
|
| - // Load the AllocationSite
|
| - __ Peek(x14, 2 * kXRegSize);
|
| - ASSERT_EQ(1 * kPointerSize, AllocationMemento::kAllocationSiteOffset);
|
| - __ Str(x14, MemOperand(first_prop, kPointerSize, PostIndex));
|
| - first_prop = NoReg;
|
| - } else {
|
| - // Fill all of the property fields with undef.
|
| - __ FillFields(first_prop, prop_fields, undef);
|
| - first_prop = NoReg;
|
| - prop_fields = NoReg;
|
| + one_pointer_filler = NoReg;
|
| + __ B(&done_field_initialization);
|
| +
|
| + __ bind(&no_inobject_slack_tracking);
|
| + if (create_memento) {
|
| + // Fill the pre-allocated fields with undef.
|
| + __ FillFields(first_prop, prop_fields, undef);
|
| + __ Add(first_prop, new_obj, Operand(obj_size, LSL, kPointerSizeLog2));
|
| + __ LoadRoot(x14, Heap::kAllocationMementoMapRootIndex);
|
| + ASSERT_EQ(0 * kPointerSize, AllocationMemento::kMapOffset);
|
| + __ Str(x14, MemOperand(first_prop, kPointerSize, PostIndex));
|
| + // Load the AllocationSite
|
| + __ Peek(x14, 2 * kXRegSize);
|
| + ASSERT_EQ(1 * kPointerSize, AllocationMemento::kAllocationSiteOffset);
|
| + __ Str(x14, MemOperand(first_prop, kPointerSize, PostIndex));
|
| + first_prop = NoReg;
|
| + } else {
|
| + // Fill all of the property fields with undef.
|
| + __ FillFields(first_prop, prop_fields, undef);
|
| + first_prop = NoReg;
|
| + prop_fields = NoReg;
|
| + }
|
| + __ bind(&done_field_initialization);
|
| }
|
|
|
| // Add the object tag to make the JSObject real, so that we can continue
|
| @@ -624,7 +638,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
|
| }
|
|
|
| // Store offset of return address for deoptimizer.
|
| - if (!is_api_function && !count_constructions) {
|
| + if (!is_api_function) {
|
| masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
|
| }
|
|
|
| @@ -675,18 +689,13 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
|
| }
|
|
|
|
|
| -void Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) {
|
| - Generate_JSConstructStubHelper(masm, false, true, false);
|
| -}
|
| -
|
| -
|
| void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
|
| - Generate_JSConstructStubHelper(masm, false, false, FLAG_pretenuring_call_new);
|
| + Generate_JSConstructStubHelper(masm, false, FLAG_pretenuring_call_new);
|
| }
|
|
|
|
|
| void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
|
| - Generate_JSConstructStubHelper(masm, true, false, false);
|
| + Generate_JSConstructStubHelper(masm, true, false);
|
| }
|
|
|
|
|
|
|