diff --git a/runtime/vm/compiler/stub_code_compiler.cc b/runtime/vm/compiler/stub_code_compiler.cc index e8783ffd830..e2717d3f5fe 100644 --- a/runtime/vm/compiler/stub_code_compiler.cc +++ b/runtime/vm/compiler/stub_code_compiler.cc @@ -1063,10 +1063,11 @@ void StubCodeCompiler::GenerateAllocateGrowableArrayStub(Assembler* assembler) { } void StubCodeCompiler::GenerateAllocateRecordStub(Assembler* assembler) { - const Register temp_reg = AllocateRecordABI::kTempReg; const Register result_reg = AllocateRecordABI::kResultReg; const Register num_fields_reg = AllocateRecordABI::kNumFieldsReg; const Register field_names_reg = AllocateRecordABI::kFieldNamesReg; + const Register temp_reg = AllocateRecordABI::kTemp1Reg; + const Register new_top_reg = AllocateRecordABI::kTemp2Reg; Label slow_case; // Check for allocation tracing. @@ -1082,16 +1083,16 @@ void StubCodeCompiler::GenerateAllocateRecordStub(Assembler* assembler) { // Now allocate the object. __ LoadFromOffset(result_reg, Address(THR, target::Thread::top_offset())); - __ AddRegisters(temp_reg, result_reg); + __ MoveRegister(new_top_reg, temp_reg); + __ AddRegisters(new_top_reg, result_reg); // Check if the allocation fits into the remaining space. - __ CompareWithMemoryValue(temp_reg, + __ CompareWithMemoryValue(new_top_reg, Address(THR, target::Thread::end_offset())); __ BranchIf(UNSIGNED_GREATER_EQUAL, &slow_case); // Successfully allocated the object, now update top to point to // next object start and initialize the object. - __ StoreToOffset(temp_reg, Address(THR, target::Thread::top_offset())); - __ SubRegisters(temp_reg, result_reg); + __ StoreToOffset(new_top_reg, Address(THR, target::Thread::top_offset())); __ AddImmediate(result_reg, kHeapObjectTag); // Calculate the size tag. @@ -1126,6 +1127,37 @@ void StubCodeCompiler::GenerateAllocateRecordStub(Assembler* assembler) { FieldAddress(result_reg, target::Record::field_names_offset()), field_names_reg); + // Initialize the remaining words of the object. + { + const Register field_reg = field_names_reg; +#if defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_RISCV32) || \ + defined(TARGET_ARCH_RISCV64) + const Register null_reg = NULL_REG; +#else + const Register null_reg = temp_reg; + __ LoadObject(null_reg, NullObject()); +#endif + + Label loop, done; + __ AddImmediate(field_reg, result_reg, + target::Record::field_offset(0) - kHeapObjectTag); + __ CompareRegisters(field_reg, new_top_reg); + __ BranchIf(UNSIGNED_GREATER_EQUAL, &done, Assembler::kNearJump); + + __ Bind(&loop); + for (intptr_t offset = 0; offset < target::kObjectAlignment; + offset += target::kCompressedWordSize) { + __ StoreCompressedIntoObjectNoBarrier( + result_reg, Address(field_reg, offset), null_reg); + } + // Safe to only check every kObjectAlignment bytes instead of each word. + ASSERT(kAllocationRedZoneSize >= target::kObjectAlignment); + __ AddImmediate(field_reg, target::kObjectAlignment); + __ CompareRegisters(field_reg, new_top_reg); + __ BranchIf(UNSIGNED_LESS, &loop, Assembler::kNearJump); + __ Bind(&done); + } + __ Ret(); __ Bind(&slow_case); diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h index 4780ecf3d87..7a28be8d402 100644 --- a/runtime/vm/constants_arm.h +++ b/runtime/vm/constants_arm.h @@ -519,7 +519,8 @@ struct AllocateRecordABI { static const Register kResultReg = AllocateObjectABI::kResultReg; static const Register kNumFieldsReg = R2; static const Register kFieldNamesReg = R1; - static const Register kTempReg = R3; + static const Register kTemp1Reg = R3; + static const Register kTemp2Reg = R4; }; // ABI for AllocateTypedDataArrayStub. diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h index 20a9a118395..766aca18613 100644 --- a/runtime/vm/constants_arm64.h +++ b/runtime/vm/constants_arm64.h @@ -353,7 +353,8 @@ struct AllocateRecordABI { static const Register kResultReg = AllocateObjectABI::kResultReg; static const Register kNumFieldsReg = R2; static const Register kFieldNamesReg = R1; - static const Register kTempReg = R3; + static const Register kTemp1Reg = R3; + static const Register kTemp2Reg = R4; }; // ABI for AllocateTypedDataArrayStub. diff --git a/runtime/vm/constants_ia32.h b/runtime/vm/constants_ia32.h index f3062569369..3da47f9000a 100644 --- a/runtime/vm/constants_ia32.h +++ b/runtime/vm/constants_ia32.h @@ -248,7 +248,8 @@ struct AllocateRecordABI { static const Register kResultReg = AllocateObjectABI::kResultReg; static const Register kNumFieldsReg = EDX; static const Register kFieldNamesReg = ECX; - static const Register kTempReg = EBX; + static const Register kTemp1Reg = EBX; + static const Register kTemp2Reg = EDI; }; // ABI for AllocateTypedDataArrayStub. diff --git a/runtime/vm/constants_riscv.h b/runtime/vm/constants_riscv.h index e84369f56e4..01604b8bd60 100644 --- a/runtime/vm/constants_riscv.h +++ b/runtime/vm/constants_riscv.h @@ -362,7 +362,8 @@ struct AllocateRecordABI { static const Register kResultReg = AllocateObjectABI::kResultReg; static const Register kNumFieldsReg = T2; static const Register kFieldNamesReg = T1; - static const Register kTempReg = T3; + static const Register kTemp1Reg = T3; + static const Register kTemp2Reg = T4; }; // ABI for AllocateTypedDataArrayStub. diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h index a3355b2a01c..1111d600e12 100644 --- a/runtime/vm/constants_x64.h +++ b/runtime/vm/constants_x64.h @@ -324,7 +324,8 @@ struct AllocateRecordABI { static const Register kResultReg = AllocateObjectABI::kResultReg; static const Register kNumFieldsReg = R10; static const Register kFieldNamesReg = RBX; - static const Register kTempReg = RDX; + static const Register kTemp1Reg = RDX; + static const Register kTemp2Reg = RCX; }; // ABI for AllocateTypedDataArrayStub.