diff mbox

[PULL,20/21] Revert use of DEFINE_MACHINE() for registrations of multiple machines

Message ID 1442673810-2679-21-git-send-email-afaerber@suse.de
State New
Headers show

Commit Message

Andreas Färber Sept. 19, 2015, 2:43 p.m. UTC
The script used for converting from QEMUMachine had used one
DEFINE_MACHINE() per machine registered. In cases where multiple
machines are registered from one source file, avoid the excessive
generation of module init functions by reverting this unrolling.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 hw/arm/exynos4_boards.c |  28 +++++++++++--
 hw/arm/gumstix.c        |  28 +++++++++++--
 hw/arm/highbank.c       |  28 +++++++++++--
 hw/arm/nseries.c        |  28 +++++++++++--
 hw/arm/omap_sx1.c       |  28 +++++++++++--
 hw/arm/realview.c       |  50 +++++++++++++++++++----
 hw/arm/spitz.c          |  50 +++++++++++++++++++----
 hw/arm/stellaris.c      |  28 +++++++++++--
 hw/arm/versatilepb.c    |  28 +++++++++++--
 hw/lm32/lm32_boards.c   |  28 +++++++++++--
 hw/mips/mips_jazz.c     |  28 +++++++++++--
 hw/ppc/ppc405_boards.c  |  28 +++++++++++--
 hw/sparc/sun4m.c        | 104 +++++++++++++++++++++++++++++++++++++++---------
 hw/sparc64/sun4u.c      |  38 +++++++++++++++---
 hw/xtensa/xtfpga.c      |  50 +++++++++++++++++++----
 15 files changed, 484 insertions(+), 88 deletions(-)

Comments

Eduardo Habkost Sept. 21, 2015, 3:49 p.m. UTC | #1
On Sat, Sep 19, 2015 at 04:43:29PM +0200, Andreas Färber wrote:
> The script used for converting from QEMUMachine had used one
> DEFINE_MACHINE() per machine registered. In cases where multiple
> machines are registered from one source file, avoid the excessive
> generation of module init functions by reverting this unrolling.

Why is that a problem?
Andreas Färber Sept. 21, 2015, 3:52 p.m. UTC | #2
Am 21.09.2015 um 17:49 schrieb Eduardo Habkost:
> On Sat, Sep 19, 2015 at 04:43:29PM +0200, Andreas Färber wrote:
>> The script used for converting from QEMUMachine had used one
>> DEFINE_MACHINE() per machine registered. In cases where multiple
>> machines are registered from one source file, avoid the excessive
>> generation of module init functions by reverting this unrolling.
> 
> Why is that a problem?

It's unnecessary code bloat and it blocks the usual QOM patterns. See
the follow-up series for an example where an abstract base type helps,
which your macro does not allow.

Regards,
Andreas
Eduardo Habkost Sept. 21, 2015, 5:24 p.m. UTC | #3
On Mon, Sep 21, 2015 at 05:52:47PM +0200, Andreas Färber wrote:
> Am 21.09.2015 um 17:49 schrieb Eduardo Habkost:
> > On Sat, Sep 19, 2015 at 04:43:29PM +0200, Andreas Färber wrote:
> >> The script used for converting from QEMUMachine had used one
> >> DEFINE_MACHINE() per machine registered. In cases where multiple
> >> machines are registered from one source file, avoid the excessive
> >> generation of module init functions by reverting this unrolling.
> > 
> > Why is that a problem?
> 
> It's unnecessary code bloat and it blocks the usual QOM patterns. See
> the follow-up series for an example where an abstract base type helps,
> which your macro does not allow.

Do you have any numbers on the actual bloat impact? Personally, I
think the reduction of boilerplate code is worth the extra bytes
in the binary. Files that register lots of simple machine classes
are exactly the use case I had in mind when adding the macro.

About the cases where an abstract base type helps, I agree
DEFINE_MACHINE isn't appropriate, but in those cases I would use
a macro like DEFINE_PC_MACHINE to reduce boilerplate code anyway.

But I don't mind too much either way: if the maintainer of the
corresponding machine code prefers to not reduce boilerplate code
using a macro, that's OK to me. I am happy now that QEMUMachine
is gone.
Eduardo Habkost Sept. 21, 2015, 5:57 p.m. UTC | #4
On Mon, Sep 21, 2015 at 02:24:51PM -0300, Eduardo Habkost wrote:
> On Mon, Sep 21, 2015 at 05:52:47PM +0200, Andreas Färber wrote:
> > Am 21.09.2015 um 17:49 schrieb Eduardo Habkost:
> > > On Sat, Sep 19, 2015 at 04:43:29PM +0200, Andreas Färber wrote:
> > >> The script used for converting from QEMUMachine had used one
> > >> DEFINE_MACHINE() per machine registered. In cases where multiple
> > >> machines are registered from one source file, avoid the excessive
> > >> generation of module init functions by reverting this unrolling.
> > > 
> > > Why is that a problem?
> > 
> > It's unnecessary code bloat and it blocks the usual QOM patterns. See
> > the follow-up series for an example where an abstract base type helps,
> > which your macro does not allow.
> 
> Do you have any numbers on the actual bloat impact?

This is what I see on x86_64:

$ readelf -W -s before/qemu-system-arm | grep smdkc210
  2675: 00000000001422b0    12 FUNC    LOCAL  DEFAULT   13 exynos4_machine_smdkc210_machine_init_register_types
  2676: 00000000007051c0   104 OBJECT  LOCAL  DEFAULT   23 exynos4_machine_smdkc210_machine_init_typeinfo
  2680: 0000000000142310    72 FUNC    LOCAL  DEFAULT   13 exynos4_machine_smdkc210_machine_init_class_init
  2682: 00000000001424b0   264 FUNC    LOCAL  DEFAULT   13 smdkc210_init
  2693: 00000000000a4d50    17 FUNC    LOCAL  DEFAULT   13 do_qemu_init_exynos4_machine_smdkc210_machine_init_register_types

$ readelf -W -s after/qemu-system-arm | grep smdkc210
  2675: 00000000007041c0   104 OBJECT  LOCAL  DEFAULT   23 smdkc210_type
  2676: 0000000000141ff0    72 FUNC    LOCAL  DEFAULT   13 smdkc210_class_init
  2678: 00000000001421e0   264 FUNC    LOCAL  DEFAULT   13 smdkc210_init

An additional type_register_static() call inside an existing type_init()
function adds 16 bytes to the function.

An additional type_init() functions adds 29 bytes:
* 12 bytes for the the function calling type_register_static()
* 17 bytes for the do_qemu_init_*() function

So, you are saving 13 bytes for each machine class.

For comparison on the existing per-machine-class bloat, each new machine class
already adds at least:
* 104 bytes for the TypeInfo object
* 240 bytes for each MachineClass struct allocated at runtime when
  find_machine() runs object_class_get_list()
* A variable number of bytes for strings, class_init and other machine
  code (336 bytes for class_init and instance_init, in the smdkc210
  case)

I would happily add extra 13 bytes for each machine class if it means simpler
code.
diff mbox

Patch

diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
index fadf372..da82b27 100644
--- a/hw/arm/exynos4_boards.c
+++ b/hw/arm/exynos4_boards.c
@@ -144,20 +144,40 @@  static void smdkc210_init(MachineState *machine)
     arm_load_kernel(ARM_CPU(first_cpu), &exynos4_board_binfo);
 }
 
-static void exynos4_machine_nuri_machine_init(MachineClass *mc)
+static void nuri_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Samsung NURI board (Exynos4210)";
     mc->init = nuri_init;
     mc->max_cpus = EXYNOS4210_NCPUS;
 }
 
-DEFINE_MACHINE("nuri", exynos4_machine_nuri_machine_init)
+static const TypeInfo nuri_type = {
+    .name = MACHINE_TYPE_NAME("nuri"),
+    .parent = TYPE_MACHINE,
+    .class_init = nuri_class_init,
+};
 
-static void exynos4_machine_smdkc210_machine_init(MachineClass *mc)
+static void smdkc210_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Samsung SMDKC210 board (Exynos4210)";
     mc->init = smdkc210_init;
     mc->max_cpus = EXYNOS4210_NCPUS;
 }
 
-DEFINE_MACHINE("smdkc210", exynos4_machine_smdkc210_machine_init)
+static const TypeInfo smdkc210_type = {
+    .name = MACHINE_TYPE_NAME("smdkc210"),
+    .parent = TYPE_MACHINE,
+    .class_init = smdkc210_class_init,
+};
+
+static void exynos4_machines_init(void)
+{
+    type_register_static(&nuri_type);
+    type_register_static(&smdkc210_type);
+}
+
+machine_init(exynos4_machines_init)
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
index 6dc98c8..32ad041 100644
--- a/hw/arm/gumstix.c
+++ b/hw/arm/gumstix.c
@@ -121,18 +121,38 @@  static void verdex_init(MachineState *machine)
                     qdev_get_gpio_in(cpu->gpio, 99));
 }
 
-static void connex_machine_init(MachineClass *mc)
+static void connex_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Gumstix Connex (PXA255)";
     mc->init = connex_init;
 }
 
-DEFINE_MACHINE("connex", connex_machine_init)
+static const TypeInfo connex_type = {
+    .name = MACHINE_TYPE_NAME("connex"),
+    .parent = TYPE_MACHINE,
+    .class_init = connex_class_init,
+};
 
-static void verdex_machine_init(MachineClass *mc)
+static void verdex_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Gumstix Verdex (PXA270)";
     mc->init = verdex_init;
 }
 
-DEFINE_MACHINE("verdex", verdex_machine_init)
+static const TypeInfo verdex_type = {
+    .name = MACHINE_TYPE_NAME("verdex"),
+    .parent = TYPE_MACHINE,
+    .class_init = verdex_class_init,
+};
+
+static void gumstix_machine_init(void)
+{
+    type_register_static(&connex_type);
+    type_register_static(&verdex_type);
+}
+
+machine_init(gumstix_machine_init)
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index 9b2887e..be04b27 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -391,22 +391,42 @@  static void midway_init(MachineState *machine)
     calxeda_init(machine, CALXEDA_MIDWAY);
 }
 
-static void highbank_machine_init(MachineClass *mc)
+static void highbank_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Calxeda Highbank (ECX-1000)";
     mc->init = highbank_init;
     mc->block_default_type = IF_SCSI;
     mc->max_cpus = 4;
 }
 
-DEFINE_MACHINE("highbank", highbank_machine_init)
+static const TypeInfo highbank_type = {
+    .name = MACHINE_TYPE_NAME("highbank"),
+    .parent = TYPE_MACHINE,
+    .class_init = highbank_class_init,
+};
 
-static void midway_machine_init(MachineClass *mc)
+static void midway_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Calxeda Midway (ECX-2000)";
     mc->init = midway_init;
     mc->block_default_type = IF_SCSI;
     mc->max_cpus = 4;
 }
 
-DEFINE_MACHINE("midway", midway_machine_init)
+static const TypeInfo midway_type = {
+    .name = MACHINE_TYPE_NAME("midway"),
+    .parent = TYPE_MACHINE,
+    .class_init = midway_class_init,
+};
+
+static void calxeda_machines_init(void)
+{
+    type_register_static(&highbank_type);
+    type_register_static(&midway_type);
+}
+
+machine_init(calxeda_machines_init)
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
index af28449..6a6b3e6 100644
--- a/hw/arm/nseries.c
+++ b/hw/arm/nseries.c
@@ -1413,20 +1413,40 @@  static void n810_init(MachineState *machine)
     n8x0_init(machine, &n810_binfo, 810);
 }
 
-static void n800_machine_init(MachineClass *mc)
+static void n800_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Nokia N800 tablet aka. RX-34 (OMAP2420)";
     mc->init = n800_init;
     mc->default_boot_order = "";
 }
 
-DEFINE_MACHINE("n800", n800_machine_init)
+static const TypeInfo n800_type = {
+    .name = MACHINE_TYPE_NAME("n800"),
+    .parent = TYPE_MACHINE,
+    .class_init = n800_class_init,
+};
 
-static void n810_machine_init(MachineClass *mc)
+static void n810_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Nokia N810 tablet aka. RX-44 (OMAP2420)";
     mc->init = n810_init;
     mc->default_boot_order = "";
 }
 
-DEFINE_MACHINE("n810", n810_machine_init)
+static const TypeInfo n810_type = {
+    .name = MACHINE_TYPE_NAME("n810"),
+    .parent = TYPE_MACHINE,
+    .class_init = n810_class_init,
+};
+
+static void nseries_machine_init(void)
+{
+    type_register_static(&n800_type);
+    type_register_static(&n810_type);
+}
+
+machine_init(nseries_machine_init)
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
index 68924fc..8eaf8f3 100644
--- a/hw/arm/omap_sx1.c
+++ b/hw/arm/omap_sx1.c
@@ -217,18 +217,38 @@  static void sx1_init_v2(MachineState *machine)
     sx1_init(machine, 2);
 }
 
-static void sx1_machine_v2_machine_init(MachineClass *mc)
+static void sx1_machine_v2_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Siemens SX1 (OMAP310) V2";
     mc->init = sx1_init_v2;
 }
 
-DEFINE_MACHINE("sx1", sx1_machine_v2_machine_init)
+static const TypeInfo sx1_machine_v2_type = {
+    .name = MACHINE_TYPE_NAME("sx1"),
+    .parent = TYPE_MACHINE,
+    .class_init = sx1_machine_v2_class_init,
+};
 
-static void sx1_machine_v1_machine_init(MachineClass *mc)
+static void sx1_machine_v1_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Siemens SX1 (OMAP310) V1";
     mc->init = sx1_init_v1;
 }
 
-DEFINE_MACHINE("sx1-v1", sx1_machine_v1_machine_init)
+static const TypeInfo sx1_machine_v1_type = {
+    .name = MACHINE_TYPE_NAME("sx1-v1"),
+    .parent = TYPE_MACHINE,
+    .class_init = sx1_machine_v1_class_init,
+};
+
+static void sx1_machine_init(void)
+{
+    type_register_static(&sx1_machine_v1_type);
+    type_register_static(&sx1_machine_v2_type);
+}
+
+machine_init(sx1_machine_init)
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index 6c83817..e14828d 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -399,39 +399,73 @@  static void realview_pbx_a9_init(MachineState *machine)
     realview_init(machine, BOARD_PBX_A9);
 }
 
-static void realview_eb_machine_init(MachineClass *mc)
+static void realview_eb_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "ARM RealView Emulation Baseboard (ARM926EJ-S)";
     mc->init = realview_eb_init;
     mc->block_default_type = IF_SCSI;
 }
 
-DEFINE_MACHINE("realview-eb", realview_eb_machine_init)
+static const TypeInfo realview_eb_type = {
+    .name = MACHINE_TYPE_NAME("realview-eb"),
+    .parent = TYPE_MACHINE,
+    .class_init = realview_eb_class_init,
+};
 
-static void realview_eb_mpcore_machine_init(MachineClass *mc)
+static void realview_eb_mpcore_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "ARM RealView Emulation Baseboard (ARM11MPCore)";
     mc->init = realview_eb_mpcore_init;
     mc->block_default_type = IF_SCSI;
     mc->max_cpus = 4;
 }
 
-DEFINE_MACHINE("realview-eb-mpcore", realview_eb_mpcore_machine_init)
+static const TypeInfo realview_eb_mpcore_type = {
+    .name = MACHINE_TYPE_NAME("realview-eb-mpcore"),
+    .parent = TYPE_MACHINE,
+    .class_init = realview_eb_mpcore_class_init,
+};
 
-static void realview_pb_a8_machine_init(MachineClass *mc)
+static void realview_pb_a8_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "ARM RealView Platform Baseboard for Cortex-A8";
     mc->init = realview_pb_a8_init;
 }
 
-DEFINE_MACHINE("realview-pb-a8", realview_pb_a8_machine_init)
+static const TypeInfo realview_pb_a8_type = {
+    .name = MACHINE_TYPE_NAME("realview-pb-a8"),
+    .parent = TYPE_MACHINE,
+    .class_init = realview_pb_a8_class_init,
+};
 
-static void realview_pbx_a9_machine_init(MachineClass *mc)
+static void realview_pbx_a9_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "ARM RealView Platform Baseboard Explore for Cortex-A9";
     mc->init = realview_pbx_a9_init;
     mc->block_default_type = IF_SCSI;
     mc->max_cpus = 4;
 }
 
-DEFINE_MACHINE("realview-pbx-a9", realview_pbx_a9_machine_init)
+static const TypeInfo realview_pbx_a9_type = {
+    .name = MACHINE_TYPE_NAME("realview-pbx-a9"),
+    .parent = TYPE_MACHINE,
+    .class_init = realview_pbx_a9_class_init,
+};
+
+static void realview_machine_init(void)
+{
+    type_register_static(&realview_eb_type);
+    type_register_static(&realview_eb_mpcore_type);
+    type_register_static(&realview_pb_a8_type);
+    type_register_static(&realview_pbx_a9_type);
+}
+
+machine_init(realview_machine_init)
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index 0f59489..2af03be 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -972,37 +972,71 @@  static void terrier_init(MachineState *machine)
     spitz_common_init(machine, terrier, 0x33f);
 }
 
-static void akitapda_machine_init(MachineClass *mc)
+static void akitapda_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Akita PDA (PXA270)";
     mc->init = akita_init;
 }
 
-DEFINE_MACHINE("akita", akitapda_machine_init)
+static const TypeInfo akitapda_type = {
+    .name = MACHINE_TYPE_NAME("akita"),
+    .parent = TYPE_MACHINE,
+    .class_init = akitapda_class_init,
+};
 
-static void spitzpda_machine_init(MachineClass *mc)
+static void spitzpda_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Spitz PDA (PXA270)";
     mc->init = spitz_init;
 }
 
-DEFINE_MACHINE("spitz", spitzpda_machine_init)
+static const TypeInfo spitzpda_type = {
+    .name = MACHINE_TYPE_NAME("spitz"),
+    .parent = TYPE_MACHINE,
+    .class_init = spitzpda_class_init,
+};
 
-static void borzoipda_machine_init(MachineClass *mc)
+static void borzoipda_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Borzoi PDA (PXA270)";
     mc->init = borzoi_init;
 }
 
-DEFINE_MACHINE("borzoi", borzoipda_machine_init)
+static const TypeInfo borzoipda_type = {
+    .name = MACHINE_TYPE_NAME("borzoi"),
+    .parent = TYPE_MACHINE,
+    .class_init = borzoipda_class_init,
+};
 
-static void terrierpda_machine_init(MachineClass *mc)
+static void terrierpda_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Terrier PDA (PXA270)";
     mc->init = terrier_init;
 }
 
-DEFINE_MACHINE("terrier", terrierpda_machine_init)
+static const TypeInfo terrierpda_type = {
+    .name = MACHINE_TYPE_NAME("terrier"),
+    .parent = TYPE_MACHINE,
+    .class_init = terrierpda_class_init,
+};
+
+static void spitz_machine_init(void)
+{
+    type_register_static(&akitapda_type);
+    type_register_static(&spitzpda_type);
+    type_register_static(&borzoipda_type);
+    type_register_static(&terrierpda_type);
+}
+
+machine_init(spitz_machine_init)
 
 static bool is_version_0(void *opaque, int version_id)
 {
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
index a97d9e3..3d6486f 100644
--- a/hw/arm/stellaris.c
+++ b/hw/arm/stellaris.c
@@ -1366,21 +1366,41 @@  static void lm3s6965evb_init(MachineState *machine)
     stellaris_init(kernel_filename, cpu_model, &stellaris_boards[1]);
 }
 
-static void lm3s811evb_machine_init(MachineClass *mc)
+static void lm3s811evb_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Stellaris LM3S811EVB";
     mc->init = lm3s811evb_init;
 }
 
-DEFINE_MACHINE("lm3s811evb", lm3s811evb_machine_init)
+static const TypeInfo lm3s811evb_type = {
+    .name = MACHINE_TYPE_NAME("lm3s811evb"),
+    .parent = TYPE_MACHINE,
+    .class_init = lm3s811evb_class_init,
+};
 
-static void lm3s6965evb_machine_init(MachineClass *mc)
+static void lm3s6965evb_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Stellaris LM3S6965EVB";
     mc->init = lm3s6965evb_init;
 }
 
-DEFINE_MACHINE("lm3s6965evb", lm3s6965evb_machine_init)
+static const TypeInfo lm3s6965evb_type = {
+    .name = MACHINE_TYPE_NAME("lm3s6965evb"),
+    .parent = TYPE_MACHINE,
+    .class_init = lm3s6965evb_class_init,
+};
+
+static void stellaris_machine_init(void)
+{
+    type_register_static(&lm3s811evb_type);
+    type_register_static(&lm3s6965evb_type);
+}
+
+machine_init(stellaris_machine_init)
 
 static void stellaris_i2c_class_init(ObjectClass *klass, void *data)
 {
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index 54281f4..912c290 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -391,23 +391,43 @@  static void vab_init(MachineState *machine)
     versatile_init(machine, 0x25e);
 }
 
-static void versatilepb_machine_init(MachineClass *mc)
+static void versatilepb_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "ARM Versatile/PB (ARM926EJ-S)";
     mc->init = vpb_init;
     mc->block_default_type = IF_SCSI;
 }
 
-DEFINE_MACHINE("versatilepb", versatilepb_machine_init)
+static const TypeInfo versatilepb_type = {
+    .name = MACHINE_TYPE_NAME("versatilepb"),
+    .parent = TYPE_MACHINE,
+    .class_init = versatilepb_class_init,
+};
 
-static void versatileab_machine_init(MachineClass *mc)
+static void versatileab_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "ARM Versatile/AB (ARM926EJ-S)";
     mc->init = vab_init;
     mc->block_default_type = IF_SCSI;
 }
 
-DEFINE_MACHINE("versatileab", versatileab_machine_init)
+static const TypeInfo versatileab_type = {
+    .name = MACHINE_TYPE_NAME("versatileab"),
+    .parent = TYPE_MACHINE,
+    .class_init = versatileab_class_init,
+};
+
+static void versatile_machine_init(void)
+{
+    type_register_static(&versatilepb_type);
+    type_register_static(&versatileab_type);
+}
+
+machine_init(versatile_machine_init)
 
 static void vpb_sic_class_init(ObjectClass *klass, void *data)
 {
diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c
index 04d2066..8e17a82 100644
--- a/hw/lm32/lm32_boards.c
+++ b/hw/lm32/lm32_boards.c
@@ -292,20 +292,40 @@  static void lm32_uclinux_init(MachineState *machine)
     qemu_register_reset(main_cpu_reset, reset_info);
 }
 
-static void lm32_evr_machine_init(MachineClass *mc)
+static void lm32_evr_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "LatticeMico32 EVR32 eval system";
     mc->init = lm32_evr_init;
     mc->is_default = 1;
 }
 
-DEFINE_MACHINE("lm32-evr", lm32_evr_machine_init)
+static const TypeInfo lm32_evr_type = {
+    .name = MACHINE_TYPE_NAME("lm32-evr"),
+    .parent = TYPE_MACHINE,
+    .class_init = lm32_evr_class_init,
+};
 
-static void lm32_uclinux_machine_init(MachineClass *mc)
+static void lm32_uclinux_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "lm32 platform for uClinux and u-boot by Theobroma Systems";
     mc->init = lm32_uclinux_init;
     mc->is_default = 0;
 }
 
-DEFINE_MACHINE("lm32-uclinux", lm32_uclinux_machine_init)
+static const TypeInfo lm32_uclinux_type = {
+    .name = MACHINE_TYPE_NAME("lm32-uclinux"),
+    .parent = TYPE_MACHINE,
+    .class_init = lm32_uclinux_class_init,
+};
+
+static void lm32_machine_init(void)
+{
+    type_register_static(&lm32_evr_type);
+    type_register_static(&lm32_uclinux_type);
+}
+
+machine_init(lm32_machine_init)
diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
index d3627ba..1ab885b 100644
--- a/hw/mips/mips_jazz.c
+++ b/hw/mips/mips_jazz.c
@@ -349,20 +349,40 @@  void mips_pica61_init(MachineState *machine)
     mips_jazz_init(machine, JAZZ_PICA61);
 }
 
-static void mips_magnum_machine_init(MachineClass *mc)
+static void mips_magnum_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "MIPS Magnum";
     mc->init = mips_magnum_init;
     mc->block_default_type = IF_SCSI;
 }
 
-DEFINE_MACHINE("magnum", mips_magnum_machine_init)
+static const TypeInfo mips_magnum_type = {
+    .name = MACHINE_TYPE_NAME("magnum"),
+    .parent = TYPE_MACHINE,
+    .class_init = mips_magnum_class_init,
+};
 
-static void mips_pica61_machine_init(MachineClass *mc)
+static void mips_pica61_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Acer Pica 61";
     mc->init = mips_pica61_init;
     mc->block_default_type = IF_SCSI;
 }
 
-DEFINE_MACHINE("pica61", mips_pica61_machine_init)
+static const TypeInfo mips_pica61_type = {
+    .name = MACHINE_TYPE_NAME("pica61"),
+    .parent = TYPE_MACHINE,
+    .class_init = mips_pica61_class_init,
+};
+
+static void mips_jazz_machine_init(void)
+{
+    type_register_static(&mips_magnum_type);
+    type_register_static(&mips_pica61_type);
+}
+
+machine_init(mips_jazz_machine_init)
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 56980bf..ec87587 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -369,13 +369,19 @@  static void ref405ep_init(MachineState *machine)
 #endif
 }
 
-static void ref405ep_machine_init(MachineClass *mc)
+static void ref405ep_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "ref405ep";
     mc->init = ref405ep_init;
 }
 
-DEFINE_MACHINE("ref405ep", ref405ep_machine_init)
+static const TypeInfo ref405ep_type = {
+    .name = MACHINE_TYPE_NAME("ref405ep"),
+    .parent = TYPE_MACHINE,
+    .class_init = ref405ep_class_init,
+};
 
 /*****************************************************************************/
 /* AMCC Taihu evaluation board */
@@ -667,10 +673,24 @@  static void taihu_405ep_init(MachineState *machine)
 #endif
 }
 
-static void taihu_machine_init(MachineClass *mc)
+static void taihu_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "taihu";
     mc->init = taihu_405ep_init;
 }
 
-DEFINE_MACHINE("taihu", taihu_machine_init)
+static const TypeInfo taihu_type = {
+    .name = MACHINE_TYPE_NAME("taihu"),
+    .parent = TYPE_MACHINE,
+    .class_init = taihu_class_init,
+};
+
+static void ppc405_machine_init(void)
+{
+    type_register_static(&ref405ep_type);
+    type_register_static(&taihu_type);
+}
+
+machine_init(ppc405_machine_init)
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 092e250..9f1917f 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -1420,8 +1420,10 @@  static void sbook_init(MachineState *machine)
     sun4m_hw_init(&sun4m_hwdefs[8], machine);
 }
 
-static void ss5_machine_init(MachineClass *mc)
+static void ss5_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Sun4m platform, SPARCstation 5";
     mc->init = ss5_init;
     mc->block_default_type = IF_SCSI;
@@ -1429,10 +1431,16 @@  static void ss5_machine_init(MachineClass *mc)
     mc->default_boot_order = "c";
 }
 
-DEFINE_MACHINE("SS-5", ss5_machine_init)
+static const TypeInfo ss5_type = {
+    .name = MACHINE_TYPE_NAME("SS-5"),
+    .parent = TYPE_MACHINE,
+    .class_init = ss5_class_init,
+};
 
-static void ss10_machine_init(MachineClass *mc)
+static void ss10_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Sun4m platform, SPARCstation 10";
     mc->init = ss10_init;
     mc->block_default_type = IF_SCSI;
@@ -1440,10 +1448,16 @@  static void ss10_machine_init(MachineClass *mc)
     mc->default_boot_order = "c";
 }
 
-DEFINE_MACHINE("SS-10", ss10_machine_init)
+static const TypeInfo ss10_type = {
+    .name = MACHINE_TYPE_NAME("SS-10"),
+    .parent = TYPE_MACHINE,
+    .class_init = ss10_class_init,
+};
 
-static void ss600mp_machine_init(MachineClass *mc)
+static void ss600mp_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Sun4m platform, SPARCserver 600MP";
     mc->init = ss600mp_init;
     mc->block_default_type = IF_SCSI;
@@ -1451,10 +1465,16 @@  static void ss600mp_machine_init(MachineClass *mc)
     mc->default_boot_order = "c";
 }
 
-DEFINE_MACHINE("SS-600MP", ss600mp_machine_init)
+static const TypeInfo ss600mp_type = {
+    .name = MACHINE_TYPE_NAME("SS-600MP"),
+    .parent = TYPE_MACHINE,
+    .class_init = ss600mp_class_init,
+};
 
-static void ss20_machine_init(MachineClass *mc)
+static void ss20_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Sun4m platform, SPARCstation 20";
     mc->init = ss20_init;
     mc->block_default_type = IF_SCSI;
@@ -1462,57 +1482,91 @@  static void ss20_machine_init(MachineClass *mc)
     mc->default_boot_order = "c";
 }
 
-DEFINE_MACHINE("SS-20", ss20_machine_init)
+static const TypeInfo ss20_type = {
+    .name = MACHINE_TYPE_NAME("SS-20"),
+    .parent = TYPE_MACHINE,
+    .class_init = ss20_class_init,
+};
 
-static void voyager_machine_init(MachineClass *mc)
+static void voyager_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Sun4m platform, SPARCstation Voyager";
     mc->init = vger_init;
     mc->block_default_type = IF_SCSI;
     mc->default_boot_order = "c";
 }
 
-DEFINE_MACHINE("Voyager", voyager_machine_init)
+static const TypeInfo voyager_type = {
+    .name = MACHINE_TYPE_NAME("Voyager"),
+    .parent = TYPE_MACHINE,
+    .class_init = voyager_class_init,
+};
 
-static void ss_lx_machine_init(MachineClass *mc)
+static void ss_lx_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Sun4m platform, SPARCstation LX";
     mc->init = ss_lx_init;
     mc->block_default_type = IF_SCSI;
     mc->default_boot_order = "c";
 }
 
-DEFINE_MACHINE("LX", ss_lx_machine_init)
+static const TypeInfo ss_lx_type = {
+    .name = MACHINE_TYPE_NAME("LX"),
+    .parent = TYPE_MACHINE,
+    .class_init = ss_lx_class_init,
+};
 
-static void ss4_machine_init(MachineClass *mc)
+static void ss4_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Sun4m platform, SPARCstation 4";
     mc->init = ss4_init;
     mc->block_default_type = IF_SCSI;
     mc->default_boot_order = "c";
 }
 
-DEFINE_MACHINE("SS-4", ss4_machine_init)
+static const TypeInfo ss4_type = {
+    .name = MACHINE_TYPE_NAME("SS-4"),
+    .parent = TYPE_MACHINE,
+    .class_init = ss4_class_init,
+};
 
-static void scls_machine_init(MachineClass *mc)
+static void scls_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Sun4m platform, SPARCClassic";
     mc->init = scls_init;
     mc->block_default_type = IF_SCSI;
     mc->default_boot_order = "c";
 }
 
-DEFINE_MACHINE("SPARCClassic", scls_machine_init)
+static const TypeInfo scls_type = {
+    .name = MACHINE_TYPE_NAME("SPARCClassic"),
+    .parent = TYPE_MACHINE,
+    .class_init = scls_class_init,
+};
 
-static void sbook_machine_init(MachineClass *mc)
+static void sbook_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Sun4m platform, SPARCbook";
     mc->init = sbook_init;
     mc->block_default_type = IF_SCSI;
     mc->default_boot_order = "c";
 }
 
-DEFINE_MACHINE("SPARCbook", sbook_machine_init)
+static const TypeInfo sbook_type = {
+    .name = MACHINE_TYPE_NAME("SPARCbook"),
+    .parent = TYPE_MACHINE,
+    .class_init = sbook_class_init,
+};
 
 static void sun4m_register_types(void)
 {
@@ -1522,4 +1576,18 @@  static void sun4m_register_types(void)
     type_register_static(&ram_info);
 }
 
+static void sun4m_machine_init(void)
+{
+    type_register_static(&ss5_type);
+    type_register_static(&ss10_type);
+    type_register_static(&ss600mp_type);
+    type_register_static(&ss20_type);
+    type_register_static(&voyager_type);
+    type_register_static(&ss_lx_type);
+    type_register_static(&ss4_type);
+    type_register_static(&scls_type);
+    type_register_static(&sbook_type);
+}
+
 type_init(sun4m_register_types)
+machine_init(sun4m_machine_init)
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index ab43dc6..a6b5957 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -965,8 +965,10 @@  static void niagara_init(MachineState *machine)
     sun4uv_init(get_system_memory(), machine, &hwdefs[2]);
 }
 
-static void sun4u_machine_init(MachineClass *mc)
+static void sun4u_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Sun4u platform";
     mc->init = sun4u_init;
     mc->max_cpus = 1; /* XXX for now */
@@ -974,27 +976,43 @@  static void sun4u_machine_init(MachineClass *mc)
     mc->default_boot_order = "c";
 }
 
-DEFINE_MACHINE("sun4u", sun4u_machine_init)
+static const TypeInfo sun4u_type = {
+    .name = MACHINE_TYPE_NAME("sun4u"),
+    .parent = TYPE_MACHINE,
+    .class_init = sun4u_class_init,
+};
 
-static void sun4v_machine_init(MachineClass *mc)
+static void sun4v_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Sun4v platform";
     mc->init = sun4v_init;
     mc->max_cpus = 1; /* XXX for now */
     mc->default_boot_order = "c";
 }
 
-DEFINE_MACHINE("sun4v", sun4v_machine_init)
+static const TypeInfo sun4v_type = {
+    .name = MACHINE_TYPE_NAME("sun4v"),
+    .parent = TYPE_MACHINE,
+    .class_init = sun4v_class_init,
+};
 
-static void niagara_machine_init(MachineClass *mc)
+static void niagara_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Sun4v platform, Niagara";
     mc->init = niagara_init;
     mc->max_cpus = 1; /* XXX for now */
     mc->default_boot_order = "c";
 }
 
-DEFINE_MACHINE("Niagara", niagara_machine_init)
+static const TypeInfo niagara_type = {
+    .name = MACHINE_TYPE_NAME("Niagara"),
+    .parent = TYPE_MACHINE,
+    .class_init = niagara_class_init,
+};
 
 static void sun4u_register_types(void)
 {
@@ -1003,4 +1021,12 @@  static void sun4u_register_types(void)
     type_register_static(&ram_info);
 }
 
+static void sun4u_machine_init(void)
+{
+    type_register_static(&sun4u_type);
+    type_register_static(&sun4v_type);
+    type_register_static(&niagara_type);
+}
+
 type_init(sun4u_register_types)
+machine_init(sun4u_machine_init)
diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
index d6ddfa1..7aca1cf 100644
--- a/hw/xtensa/xtfpga.c
+++ b/hw/xtensa/xtfpga.c
@@ -428,38 +428,72 @@  static void xtensa_kc705_init(MachineState *machine)
     lx_init(&kc705_board, machine);
 }
 
-static void xtensa_lx60_machine_init(MachineClass *mc)
+static void xtensa_lx60_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "lx60 EVB (" XTENSA_DEFAULT_CPU_MODEL ")";
     mc->init = xtensa_lx60_init;
     mc->max_cpus = 4;
 }
 
-DEFINE_MACHINE("lx60", xtensa_lx60_machine_init)
+static const TypeInfo xtensa_lx60_type = {
+    .name = MACHINE_TYPE_NAME("lx60"),
+    .parent = TYPE_MACHINE,
+    .class_init = xtensa_lx60_class_init,
+};
 
-static void xtensa_lx200_machine_init(MachineClass *mc)
+static void xtensa_lx200_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "lx200 EVB (" XTENSA_DEFAULT_CPU_MODEL ")";
     mc->init = xtensa_lx200_init;
     mc->max_cpus = 4;
 }
 
-DEFINE_MACHINE("lx200", xtensa_lx200_machine_init)
+static const TypeInfo xtensa_lx200_type = {
+    .name = MACHINE_TYPE_NAME("lx200"),
+    .parent = TYPE_MACHINE,
+    .class_init = xtensa_lx200_class_init,
+};
 
-static void xtensa_ml605_machine_init(MachineClass *mc)
+static void xtensa_ml605_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "ml605 EVB (" XTENSA_DEFAULT_CPU_MODEL ")";
     mc->init = xtensa_ml605_init;
     mc->max_cpus = 4;
 }
 
-DEFINE_MACHINE("ml605", xtensa_ml605_machine_init)
+static const TypeInfo xtensa_ml605_type = {
+    .name = MACHINE_TYPE_NAME("ml605"),
+    .parent = TYPE_MACHINE,
+    .class_init = xtensa_ml605_class_init,
+};
 
-static void xtensa_kc705_machine_init(MachineClass *mc)
+static void xtensa_kc705_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "kc705 EVB (" XTENSA_DEFAULT_CPU_MODEL ")";
     mc->init = xtensa_kc705_init;
     mc->max_cpus = 4;
 }
 
-DEFINE_MACHINE("kc705", xtensa_kc705_machine_init)
+static const TypeInfo xtensa_kc705_type = {
+    .name = MACHINE_TYPE_NAME("kc705"),
+    .parent = TYPE_MACHINE,
+    .class_init = xtensa_kc705_class_init,
+};
+
+static void xtensa_lx_machines_init(void)
+{
+    type_register_static(&xtensa_lx60_type);
+    type_register_static(&xtensa_lx200_type);
+    type_register_static(&xtensa_ml605_type);
+    type_register_static(&xtensa_kc705_type);
+}
+
+machine_init(xtensa_lx_machines_init)