1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 15:47:44 +00:00

LibX86: malloc a bit less

This reduces malloc()/free() calls in `disasm /bin/id` by 30%
according to LIBC_DUMP_MALLOC_STATS.

No measurable performance change (the number of empty block hits
remains unchanged, and that's what's slow), but maybe a nice
change regardless?
This commit is contained in:
Nico Weber 2020-08-13 13:53:06 -04:00 committed by Andreas Kling
parent 8fe89cf441
commit 2c82b69bd7
2 changed files with 119 additions and 18 deletions

View file

@ -1219,24 +1219,26 @@ String Instruction::to_string(u32 origin, const SymbolProvider* symbol_provider,
builder.append("lock "); builder.append("lock ");
if (has_rep_prefix()) if (has_rep_prefix())
builder.append(m_rep_prefix == Prefix::REPNZ ? "repnz " : "repz "); builder.append(m_rep_prefix == Prefix::REPNZ ? "repnz " : "repz ");
builder.append(to_string_internal(origin, symbol_provider, x32)); to_string_internal(builder, origin, symbol_provider, x32);
return builder.to_string(); return builder.to_string();
} }
String Instruction::to_string_internal(u32 origin, const SymbolProvider* symbol_provider, bool x32) const void Instruction::to_string_internal(StringBuilder& builder, u32 origin, const SymbolProvider* symbol_provider, bool x32) const
{ {
if (!m_descriptor) if (!m_descriptor) {
return String::format("db %#02x", m_op); builder.appendf("db %#02x", m_op);
return;
StringBuilder builder; }
String mnemonic = String(m_descriptor->mnemonic).to_lowercase(); String mnemonic = String(m_descriptor->mnemonic).to_lowercase();
builder.append(mnemonic); auto append_mnemonic = [&] { builder.append(mnemonic); };
builder.append(' '); auto append_mnemonic_space = [&] {
builder.append(mnemonic);
builder.append(' ');
};
auto formatted_address = [&](FlatPtr origin, bool x32, auto offset) { auto formatted_address = [&](FlatPtr origin, bool x32, auto offset) {
StringBuilder builder;
builder.append(relative_address(origin, x32, offset)); builder.append(relative_address(origin, x32, offset));
if (symbol_provider) { if (symbol_provider) {
u32 symbol_offset = 0; u32 symbol_offset = 0;
@ -1247,7 +1249,6 @@ String Instruction::to_string_internal(u32 origin, const SymbolProvider* symbol_
builder.appendf("+%u", symbol_offset); builder.appendf("+%u", symbol_offset);
builder.append('>'); builder.append('>');
} }
return builder.to_string();
}; };
auto append_rm8 = [&] { builder.append(m_modrm.to_string_o8(*this)); }; auto append_rm8 = [&] { builder.append(m_modrm.to_string_o8(*this)); };
@ -1273,10 +1274,10 @@ String Instruction::to_string_internal(u32 origin, const SymbolProvider* symbol_
auto append_seg = [&] { builder.append(register_name(segment_register())); }; auto append_seg = [&] { builder.append(register_name(segment_register())); };
auto append_creg = [&] { builder.appendf("cr%u", register_index()); }; auto append_creg = [&] { builder.appendf("cr%u", register_index()); };
auto append_dreg = [&] { builder.appendf("dr%u", register_index()); }; auto append_dreg = [&] { builder.appendf("dr%u", register_index()); };
auto append_relative_addr = [&] { builder.append(formatted_address(origin + (m_a32 ? 6 : 4), x32, i32(m_a32 ? imm32() : imm16()))); }; auto append_relative_addr = [&] { formatted_address(origin + (m_a32 ? 6 : 4), x32, i32(m_a32 ? imm32() : imm16())); };
auto append_relative_imm8 = [&] { builder.append(formatted_address(origin + 2, x32, i8(imm8()))); }; auto append_relative_imm8 = [&] { formatted_address(origin + 2, x32, i8(imm8())); };
auto append_relative_imm16 = [&] { builder.append(formatted_address(origin + 3, x32, i16(imm16()))); }; auto append_relative_imm16 = [&] { formatted_address(origin + 3, x32, i16(imm16())); };
auto append_relative_imm32 = [&] { builder.append(formatted_address(origin + 5, x32, i32(imm32()))); }; auto append_relative_imm32 = [&] { formatted_address(origin + 5, x32, i32(imm32())); };
auto append_mm = [&] { builder.appendf("mm%u", register_index()); }; auto append_mm = [&] { builder.appendf("mm%u", register_index()); };
auto append_mmrm64 = [&] { builder.append(m_modrm.to_string_mm(*this)); }; auto append_mmrm64 = [&] { builder.append(m_modrm.to_string_mm(*this)); };
@ -1294,21 +1295,25 @@ String Instruction::to_string_internal(u32 origin, const SymbolProvider* symbol_
switch (m_descriptor->format) { switch (m_descriptor->format) {
case OP_RM8_imm8: case OP_RM8_imm8:
append_mnemonic_space();
append_rm8(); append_rm8();
append(", "); append(", ");
append_imm8(); append_imm8();
break; break;
case OP_RM16_imm8: case OP_RM16_imm8:
append_mnemonic_space();
append_rm16(); append_rm16();
append(", "); append(", ");
append_imm8(); append_imm8();
break; break;
case OP_RM32_imm8: case OP_RM32_imm8:
append_mnemonic_space();
append_rm32(); append_rm32();
append(", "); append(", ");
append_imm8(); append_imm8();
break; break;
case OP_reg16_RM16_imm8: case OP_reg16_RM16_imm8:
append_mnemonic_space();
append_reg16(); append_reg16();
append(", "); append(", ");
append_rm16(); append_rm16();
@ -1316,6 +1321,7 @@ String Instruction::to_string_internal(u32 origin, const SymbolProvider* symbol_
append_imm8(); append_imm8();
break; break;
case OP_reg32_RM32_imm8: case OP_reg32_RM32_imm8:
append_mnemonic_space();
append_reg32(); append_reg32();
append(", "); append(", ");
append_rm32(); append_rm32();
@ -1323,50 +1329,62 @@ String Instruction::to_string_internal(u32 origin, const SymbolProvider* symbol_
append_imm8(); append_imm8();
break; break;
case OP_AL_imm8: case OP_AL_imm8:
append_mnemonic_space();
append("al, "); append("al, ");
append_imm8(); append_imm8();
break; break;
case OP_imm8: case OP_imm8:
append_mnemonic_space();
append_imm8(); append_imm8();
break; break;
case OP_reg8_imm8: case OP_reg8_imm8:
append_mnemonic_space();
append_reg8(); append_reg8();
append(", "); append(", ");
append_imm8(); append_imm8();
break; break;
case OP_AX_imm8: case OP_AX_imm8:
append_mnemonic_space();
append("ax, "); append("ax, ");
append_imm8(); append_imm8();
break; break;
case OP_EAX_imm8: case OP_EAX_imm8:
append_mnemonic_space();
append("eax, "); append("eax, ");
append_imm8(); append_imm8();
break; break;
case OP_imm8_AL: case OP_imm8_AL:
append_mnemonic_space();
append_imm8(); append_imm8();
append(", al"); append(", al");
break; break;
case OP_imm8_AX: case OP_imm8_AX:
append_mnemonic_space();
append_imm8(); append_imm8();
append(", ax"); append(", ax");
break; break;
case OP_imm8_EAX: case OP_imm8_EAX:
append_mnemonic_space();
append_imm8(); append_imm8();
append(", eax"); append(", eax");
break; break;
case OP_AX_imm16: case OP_AX_imm16:
append_mnemonic_space();
append("ax, "); append("ax, ");
append_imm16(); append_imm16();
break; break;
case OP_imm16: case OP_imm16:
append_mnemonic_space();
append_imm16(); append_imm16();
break; break;
case OP_reg16_imm16: case OP_reg16_imm16:
append_mnemonic_space();
append_reg16(); append_reg16();
append(", "); append(", ");
append_imm16(); append_imm16();
break; break;
case OP_reg16_RM16_imm16: case OP_reg16_RM16_imm16:
append_mnemonic_space();
append_reg16(); append_reg16();
append(", "); append(", ");
append_rm16(); append_rm16();
@ -1374,6 +1392,7 @@ String Instruction::to_string_internal(u32 origin, const SymbolProvider* symbol_
append_imm16(); append_imm16();
break; break;
case OP_reg32_RM32_imm32: case OP_reg32_RM32_imm32:
append_mnemonic_space();
append_reg32(); append_reg32();
append(", "); append(", ");
append_rm32(); append_rm32();
@ -1381,299 +1400,375 @@ String Instruction::to_string_internal(u32 origin, const SymbolProvider* symbol_
append_imm32(); append_imm32();
break; break;
case OP_imm32: case OP_imm32:
append_mnemonic_space();
append_imm32(); append_imm32();
break; break;
case OP_EAX_imm32: case OP_EAX_imm32:
append_mnemonic_space();
append("eax, "); append("eax, ");
append_imm32(); append_imm32();
break; break;
case OP_CS: case OP_CS:
append_mnemonic_space();
append("cs"); append("cs");
break; break;
case OP_DS: case OP_DS:
append_mnemonic_space();
append("ds"); append("ds");
break; break;
case OP_ES: case OP_ES:
append_mnemonic_space();
append("es"); append("es");
break; break;
case OP_SS: case OP_SS:
append_mnemonic_space();
append("ss"); append("ss");
break; break;
case OP_FS: case OP_FS:
append_mnemonic_space();
append("fs"); append("fs");
break; break;
case OP_GS: case OP_GS:
append_mnemonic_space();
append("gs"); append("gs");
break; break;
case OP: case OP:
append_mnemonic_space();
break; break;
case OP_reg32: case OP_reg32:
append_mnemonic_space();
append_reg32(); append_reg32();
break; break;
case OP_imm16_imm8: case OP_imm16_imm8:
append_mnemonic_space();
append_imm16_1(); append_imm16_1();
append(", "); append(", ");
append_imm8_2(); append_imm8_2();
break; break;
case OP_moff8_AL: case OP_moff8_AL:
append_mnemonic_space();
append_moff(); append_moff();
append(", al"); append(", al");
break; break;
case OP_moff16_AX: case OP_moff16_AX:
append_mnemonic_space();
append_moff(); append_moff();
append(", ax"); append(", ax");
break; break;
case OP_moff32_EAX: case OP_moff32_EAX:
append_mnemonic_space();
append_moff(); append_moff();
append(", eax"); append(", eax");
break; break;
case OP_AL_moff8: case OP_AL_moff8:
append_mnemonic_space();
append("al, "); append("al, ");
append_moff(); append_moff();
break; break;
case OP_AX_moff16: case OP_AX_moff16:
append_mnemonic_space();
append("ax, "); append("ax, ");
append_moff(); append_moff();
break; break;
case OP_EAX_moff32: case OP_EAX_moff32:
append_mnemonic_space();
append("eax, "); append("eax, ");
append_moff(); append_moff();
break; break;
case OP_imm16_imm16: case OP_imm16_imm16:
append_mnemonic_space();
append_imm16_1(); append_imm16_1();
append(":"); append(":");
append_imm16_2(); append_imm16_2();
break; break;
case OP_imm16_imm32: case OP_imm16_imm32:
append_mnemonic_space();
append_imm16_1(); append_imm16_1();
append(":"); append(":");
append_imm32_2(); append_imm32_2();
break; break;
case OP_reg32_imm32: case OP_reg32_imm32:
append_mnemonic_space();
append_reg32(); append_reg32();
append(", "); append(", ");
append_imm32(); append_imm32();
break; break;
case OP_RM8_1: case OP_RM8_1:
append_mnemonic_space();
append_rm8(); append_rm8();
append(", 0x01"); append(", 0x01");
break; break;
case OP_RM16_1: case OP_RM16_1:
append_mnemonic_space();
append_rm16(); append_rm16();
append(", 0x01"); append(", 0x01");
break; break;
case OP_RM32_1: case OP_RM32_1:
append_mnemonic_space();
append_rm32(); append_rm32();
append(", 0x01"); append(", 0x01");
break; break;
case OP_RM8_CL: case OP_RM8_CL:
append_mnemonic_space();
append_rm8(); append_rm8();
append(", cl"); append(", cl");
break; break;
case OP_RM16_CL: case OP_RM16_CL:
append_mnemonic_space();
append_rm16(); append_rm16();
append(", cl"); append(", cl");
break; break;
case OP_RM32_CL: case OP_RM32_CL:
append_mnemonic_space();
append_rm32(); append_rm32();
append(", cl"); append(", cl");
break; break;
case OP_reg16: case OP_reg16:
append_mnemonic_space();
append_reg16(); append_reg16();
break; break;
case OP_AX_reg16: case OP_AX_reg16:
append_mnemonic_space();
append("ax, "); append("ax, ");
append_reg16(); append_reg16();
break; break;
case OP_EAX_reg32: case OP_EAX_reg32:
append_mnemonic_space();
append("eax, "); append("eax, ");
append_reg32(); append_reg32();
break; break;
case OP_3: case OP_3:
append_mnemonic_space();
append("0x03"); append("0x03");
break; break;
case OP_AL_DX: case OP_AL_DX:
append_mnemonic_space();
append("al, dx"); append("al, dx");
break; break;
case OP_AX_DX: case OP_AX_DX:
append_mnemonic_space();
append("ax, dx"); append("ax, dx");
break; break;
case OP_EAX_DX: case OP_EAX_DX:
append_mnemonic_space();
append("eax, dx"); append("eax, dx");
break; break;
case OP_DX_AL: case OP_DX_AL:
append_mnemonic_space();
append("dx, al"); append("dx, al");
break; break;
case OP_DX_AX: case OP_DX_AX:
append_mnemonic_space();
append("dx, ax"); append("dx, ax");
break; break;
case OP_DX_EAX: case OP_DX_EAX:
append_mnemonic_space();
append("dx, eax"); append("dx, eax");
break; break;
case OP_reg8_CL: case OP_reg8_CL:
append_mnemonic_space();
append_reg8(); append_reg8();
append(", cl"); append(", cl");
break; break;
case OP_RM8: case OP_RM8:
append_mnemonic_space();
append_rm8(); append_rm8();
break; break;
case OP_RM16: case OP_RM16:
append_mnemonic_space();
append_rm16(); append_rm16();
break; break;
case OP_RM32: case OP_RM32:
append_mnemonic_space();
append_rm32(); append_rm32();
break; break;
case OP_FPU: case OP_FPU:
append_mnemonic_space();
break; break;
case OP_FPU_reg: case OP_FPU_reg:
append_mnemonic_space();
append_fpu_reg(); append_fpu_reg();
break; break;
case OP_FPU_mem: case OP_FPU_mem:
append_mnemonic_space();
append_fpu_mem(); append_fpu_mem();
break; break;
case OP_FPU_AX16: case OP_FPU_AX16:
append_mnemonic_space();
append_fpu_ax16(); append_fpu_ax16();
break; break;
case OP_FPU_RM16: case OP_FPU_RM16:
append_mnemonic_space();
append_fpu_rm16(); append_fpu_rm16();
break; break;
case OP_FPU_RM32: case OP_FPU_RM32:
append_mnemonic_space();
append_fpu_rm32(); append_fpu_rm32();
break; break;
case OP_FPU_RM64: case OP_FPU_RM64:
append_mnemonic_space();
append_fpu_rm64(); append_fpu_rm64();
break; break;
case OP_FPU_M80: case OP_FPU_M80:
append_mnemonic_space();
append_fpu_rm80(); append_fpu_rm80();
break; break;
case OP_RM8_reg8: case OP_RM8_reg8:
append_mnemonic_space();
append_rm8(); append_rm8();
append(", "); append(", ");
append_reg8(); append_reg8();
break; break;
case OP_RM16_reg16: case OP_RM16_reg16:
append_mnemonic_space();
append_rm16(); append_rm16();
append(", "); append(", ");
append_reg16(); append_reg16();
break; break;
case OP_RM32_reg32: case OP_RM32_reg32:
append_mnemonic_space();
append_rm32(); append_rm32();
append(", "); append(", ");
append_reg32(); append_reg32();
break; break;
case OP_reg8_RM8: case OP_reg8_RM8:
append_mnemonic_space();
append_reg8(); append_reg8();
append(", "); append(", ");
append_rm8(); append_rm8();
break; break;
case OP_reg16_RM16: case OP_reg16_RM16:
append_mnemonic_space();
append_reg16(); append_reg16();
append(", "); append(", ");
append_rm16(); append_rm16();
break; break;
case OP_reg32_RM32: case OP_reg32_RM32:
append_mnemonic_space();
append_reg32(); append_reg32();
append(", "); append(", ");
append_rm32(); append_rm32();
break; break;
case OP_reg32_RM16: case OP_reg32_RM16:
append_mnemonic_space();
append_reg32(); append_reg32();
append(", "); append(", ");
append_rm16(); append_rm16();
break; break;
case OP_reg16_RM8: case OP_reg16_RM8:
append_mnemonic_space();
append_reg16(); append_reg16();
append(", "); append(", ");
append_rm8(); append_rm8();
break; break;
case OP_reg32_RM8: case OP_reg32_RM8:
append_mnemonic_space();
append_reg32(); append_reg32();
append(", "); append(", ");
append_rm8(); append_rm8();
break; break;
case OP_RM16_imm16: case OP_RM16_imm16:
append_mnemonic_space();
append_rm16(); append_rm16();
append(", "); append(", ");
append_imm16(); append_imm16();
break; break;
case OP_RM32_imm32: case OP_RM32_imm32:
append_mnemonic_space();
append_rm32(); append_rm32();
append(", "); append(", ");
append_imm32(); append_imm32();
break; break;
case OP_RM16_seg: case OP_RM16_seg:
append_mnemonic_space();
append_rm16(); append_rm16();
append(", "); append(", ");
append_seg(); append_seg();
break; break;
case OP_RM32_seg: case OP_RM32_seg:
append_mnemonic_space();
append_rm32(); append_rm32();
append(", "); append(", ");
append_seg(); append_seg();
break; break;
case OP_seg_RM16: case OP_seg_RM16:
append_mnemonic_space();
append_seg(); append_seg();
append(", "); append(", ");
append_rm16(); append_rm16();
break; break;
case OP_seg_RM32: case OP_seg_RM32:
append_mnemonic_space();
append_seg(); append_seg();
append(", "); append(", ");
append_rm32(); append_rm32();
break; break;
case OP_reg16_mem16: case OP_reg16_mem16:
append_mnemonic_space();
append_reg16(); append_reg16();
append(", "); append(", ");
append_rm16(); append_rm16();
break; break;
case OP_reg32_mem32: case OP_reg32_mem32:
append_mnemonic_space();
append_reg32(); append_reg32();
append(", "); append(", ");
append_rm32(); append_rm32();
break; break;
case OP_FAR_mem16: case OP_FAR_mem16:
append_mnemonic_space();
append("far "); append("far ");
append_rm16(); append_rm16();
break; break;
case OP_FAR_mem32: case OP_FAR_mem32:
append_mnemonic_space();
append("far "); append("far ");
append_rm32(); append_rm32();
break; break;
case OP_reg32_CR: case OP_reg32_CR:
append_mnemonic_space();
builder.append(register_name(static_cast<RegisterIndex32>(rm() & 7))); builder.append(register_name(static_cast<RegisterIndex32>(rm() & 7)));
append(", "); append(", ");
append_creg(); append_creg();
break; break;
case OP_CR_reg32: case OP_CR_reg32:
append_mnemonic_space();
append_creg(); append_creg();
append(", "); append(", ");
builder.append(register_name(static_cast<RegisterIndex32>(rm() & 7))); builder.append(register_name(static_cast<RegisterIndex32>(rm() & 7)));
break; break;
case OP_reg32_DR: case OP_reg32_DR:
append_mnemonic_space();
builder.append(register_name(static_cast<RegisterIndex32>(rm() & 7))); builder.append(register_name(static_cast<RegisterIndex32>(rm() & 7)));
append(", "); append(", ");
append_dreg(); append_dreg();
break; break;
case OP_DR_reg32: case OP_DR_reg32:
append_mnemonic_space();
append_dreg(); append_dreg();
append(", "); append(", ");
builder.append(register_name(static_cast<RegisterIndex32>(rm() & 7))); builder.append(register_name(static_cast<RegisterIndex32>(rm() & 7)));
break; break;
case OP_short_imm8: case OP_short_imm8:
append_mnemonic_space();
append("short "); append("short ");
append_relative_imm8(); append_relative_imm8();
break; break;
case OP_relimm16: case OP_relimm16:
append_mnemonic_space();
append_relative_imm16(); append_relative_imm16();
break; break;
case OP_relimm32: case OP_relimm32:
append_mnemonic_space();
append_relative_imm32(); append_relative_imm32();
break; break;
case OP_NEAR_imm: case OP_NEAR_imm:
append_mnemonic_space();
append("near "); append("near ");
append_relative_addr(); append_relative_addr();
break; break;
case OP_RM16_reg16_imm8: case OP_RM16_reg16_imm8:
append_mnemonic_space();
append_rm16(); append_rm16();
append(", "); append(", ");
append_reg16(); append_reg16();
@ -1681,6 +1776,7 @@ String Instruction::to_string_internal(u32 origin, const SymbolProvider* symbol_
append_imm8(); append_imm8();
break; break;
case OP_RM32_reg32_imm8: case OP_RM32_reg32_imm8:
append_mnemonic_space();
append_rm32(); append_rm32();
append(", "); append(", ");
append_reg32(); append_reg32();
@ -1688,36 +1784,41 @@ String Instruction::to_string_internal(u32 origin, const SymbolProvider* symbol_
append_imm8(); append_imm8();
break; break;
case OP_RM16_reg16_CL: case OP_RM16_reg16_CL:
append_mnemonic_space();
append_rm16(); append_rm16();
append(", "); append(", ");
append_reg16(); append_reg16();
append(", cl"); append(", cl");
break; break;
case OP_RM32_reg32_CL: case OP_RM32_reg32_CL:
append_mnemonic_space();
append_rm32(); append_rm32();
append(", "); append(", ");
append_reg32(); append_reg32();
append(", cl"); append(", cl");
break; break;
case OP_mm1_mm2m64: case OP_mm1_mm2m64:
append_mnemonic_space();
append_mm(); append_mm();
append(", "); append(", ");
append_mmrm64(); append_mmrm64();
break; break;
case OP_mm1m64_mm2: case OP_mm1m64_mm2:
append_mnemonic_space();
append_mm(); append_mm();
append(", "); append(", ");
append_mmrm64(); append_mmrm64();
break; break;
case InstructionPrefix: case InstructionPrefix:
return mnemonic; append_mnemonic();
break;
case InvalidFormat: case InvalidFormat:
case MultibyteWithSlash: case MultibyteWithSlash:
case __BeginFormatsWithRMByte: case __BeginFormatsWithRMByte:
case __EndFormatsWithRMByte: case __EndFormatsWithRMByte:
return String::format("(!%s)", mnemonic.characters()); builder.append(String::format("(!%s)", mnemonic.characters()));
break;
} }
return builder.to_string();
} }
String Instruction::mnemonic() const String Instruction::mnemonic() const

View file

@ -522,7 +522,7 @@ private:
template<typename InstructionStreamType> template<typename InstructionStreamType>
Instruction(InstructionStreamType&, bool o32, bool a32); Instruction(InstructionStreamType&, bool o32, bool a32);
String to_string_internal(u32 origin, const SymbolProvider*, bool x32) const; void to_string_internal(StringBuilder&, u32 origin, const SymbolProvider*, bool x32) const;
const char* reg8_name() const; const char* reg8_name() const;
const char* reg16_name() const; const char* reg16_name() const;