From f067e0eff8777f78a9f6ab8ad0af1309d907e6ba Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Wed, 30 Oct 2013 10:06:24 +0100 Subject: [PATCH] MRI-Binding: Reduce number of object allocations Previously, wrapped instances of mkxp core classes were stored as RData ivars inside the actual object. This turned out to be pointless as RData objects themselves are perfectly valid objects that can carry ivars and have parent classes. Therefore, the RData objects are now exposed directly to the user scripts, effectively halving the amount of object allocations. --- binding-mri/binding-util.h | 29 +++++++++++++++-------------- binding-mri/bitmap-binding.cpp | 3 ++- binding-mri/etc-binding.cpp | 3 ++- binding-mri/filesystem-binding.cpp | 3 ++- binding-mri/font-binding.cpp | 3 ++- binding-mri/plane-binding.cpp | 3 ++- binding-mri/sprite-binding.cpp | 3 ++- binding-mri/table-binding.cpp | 3 ++- binding-mri/tilemap-binding.cpp | 6 ++++-- binding-mri/viewport-binding.cpp | 3 ++- binding-mri/window-binding.cpp | 3 ++- 11 files changed, 37 insertions(+), 25 deletions(-) diff --git a/binding-mri/binding-util.h b/binding-mri/binding-util.h index 8bc4c93..2c9fcea 100644 --- a/binding-mri/binding-util.h +++ b/binding-mri/binding-util.h @@ -24,8 +24,6 @@ #include "./ruby/ruby.h" -#define PRIV_IV "priv" - enum RbException { RGSS = 0, @@ -68,6 +66,12 @@ void initType(rb_data_type_struct &type, const char *name, void (*freeInst)(void*)); +template +static VALUE classAllocate(VALUE klass) +{ + return rb_data_typed_object_alloc(klass, 0, rbType); +} + template static void freeInstance(void *inst) { @@ -80,24 +84,21 @@ template static inline C * getPrivateData(VALUE self) { - VALUE priv = rb_iv_get(self, PRIV_IV); - return static_cast(RTYPEDDATA_DATA(priv)); + return static_cast(RTYPEDDATA_DATA(self)); } template static inline C * getPrivateDataCheck(VALUE self, const rb_data_type_struct &type) { - VALUE priv = rb_iv_get(self, PRIV_IV); - void *obj = rb_check_typeddata(priv, &type); + void *obj = rb_check_typeddata(self, &type); return static_cast(obj); } static inline void -setPrivateData(VALUE self, void *p, const rb_data_type_struct &type) +setPrivateData(VALUE self, void *p) { - VALUE priv = rb_data_typed_object_alloc(rb_cData, p, &type); - rb_iv_set(self, PRIV_IV, priv); + RTYPEDDATA_DATA(self) = p; } inline VALUE @@ -106,7 +107,7 @@ wrapObject(void *p, const rb_data_type_struct &type) VALUE klass = rb_const_get(rb_cObject, rb_intern(type.wrap_struct_name)); VALUE obj = rb_obj_alloc(klass); - setPrivateData(obj, p, type); + setPrivateData(obj, p); return obj; } @@ -160,7 +161,7 @@ _rb_define_module_function(VALUE module, const char *name, RubyMethod func) template static inline VALUE -objectLoad(int argc, VALUE *argv, VALUE self, rb_data_type_struct &type) +objectLoad(int argc, VALUE *argv, VALUE self) { const char *data; int dataLen; @@ -172,7 +173,7 @@ objectLoad(int argc, VALUE *argv, VALUE self, rb_data_type_struct &type) GUARD_EXC( c = C::deserialize(data, dataLen); ); - setPrivateData(obj, c, type); + setPrivateData(obj, c); return obj; } @@ -192,7 +193,7 @@ rb_bool_new(bool value) #define MARSH_LOAD_FUN(Typ) \ RB_METHOD(Typ##Load) \ { \ - return objectLoad(argc, argv, self, Typ##Type); \ + return objectLoad(argc, argv, self); \ } #define CLONE_FUNC(Klass) \ @@ -213,7 +214,7 @@ rb_bool_new(bool value) Klass *k = getPrivateData(self); \ VALUE dupObj = rb_obj_clone(self); \ Klass *dupK = new Klass(*k); \ - setPrivateData(dupObj, dupK, Klass##Type); \ + setPrivateData(dupObj, dupK); \ return dupObj; \ } diff --git a/binding-mri/bitmap-binding.cpp b/binding-mri/bitmap-binding.cpp index 7243608..fd28c1a 100644 --- a/binding-mri/bitmap-binding.cpp +++ b/binding-mri/bitmap-binding.cpp @@ -51,7 +51,7 @@ RB_METHOD(bitmapInitialize) GUARD_EXC( b = new Bitmap(width, height); ) } - setPrivateData(self, b, BitmapType); + setPrivateData(self, b); /* Wrap properties */ Font *font = new Font(); @@ -300,6 +300,7 @@ bitmapBindingInit() INIT_TYPE(Bitmap); VALUE klass = rb_define_class("Bitmap", rb_cObject); + rb_define_alloc_func(klass, classAllocate<&BitmapType>); disposableBindingInit(klass); diff --git a/binding-mri/etc-binding.cpp b/binding-mri/etc-binding.cpp index f57e3c7..226ad24 100644 --- a/binding-mri/etc-binding.cpp +++ b/binding-mri/etc-binding.cpp @@ -84,7 +84,7 @@ EQUAL_FUN(Rect) param_type p1, p2, p3, p4 = last_param_def; \ rb_get_args(argc, argv, param_t_s, &p1, &p2, &p3, &p4, RB_ARG_END); \ Klass *k = new Klass(p1, p2, p3, p4); \ - setPrivateData(self, k, Klass##Type); \ + setPrivateData(self, k); \ return self; \ } @@ -156,6 +156,7 @@ CLONE_FUN(Rect) { \ INIT_TYPE(Klass); \ klass = rb_define_class(#Klass, rb_cObject); \ + rb_define_alloc_func(klass, classAllocate<&Klass##Type>); \ rb_define_class_method(klass, "_load", Klass##Load); \ serializableBindingInit(klass); \ _rb_define_method(klass, "initialize", Klass##Initialize); \ diff --git a/binding-mri/filesystem-binding.cpp b/binding-mri/filesystem-binding.cpp index 7294b4d..9c691b1 100644 --- a/binding-mri/filesystem-binding.cpp +++ b/binding-mri/filesystem-binding.cpp @@ -41,7 +41,7 @@ fileIntForPath(const char *path) VALUE obj = rb_obj_alloc(klass); - setPrivateData(obj, ops, FileIntType); + setPrivateData(obj, ops); return obj; } @@ -198,6 +198,7 @@ fileIntBindingInit() initType(FileIntType, "FileInt", fileIntFreeInstance); VALUE klass = rb_define_class("FileInt", rb_cIO); + rb_define_alloc_func(klass, classAllocate<&FileIntType>); _rb_define_method(klass, "read", fileIntRead); _rb_define_method(klass, "getbyte", fileIntGetByte); diff --git a/binding-mri/font-binding.cpp b/binding-mri/font-binding.cpp index 2db688d..16f830e 100644 --- a/binding-mri/font-binding.cpp +++ b/binding-mri/font-binding.cpp @@ -45,7 +45,7 @@ RB_METHOD(fontInitialize) Font *f = new Font(name, size); - setPrivateData(self, f, FontType); + setPrivateData(self, f); /* Wrap property objects */ f->setColor(new Color(*f->getColor())); @@ -151,6 +151,7 @@ fontBindingInit() INIT_TYPE(Font); VALUE klass = rb_define_class("Font", rb_cObject); + rb_define_alloc_func(klass, classAllocate<&FontType>); Font::setDefaultColor(new Color(*Font::getDefaultColor())); wrapProperty(klass, Font::getDefaultColor(), "default_color", ColorType); diff --git a/binding-mri/plane-binding.cpp b/binding-mri/plane-binding.cpp index f203818..3fdb808 100644 --- a/binding-mri/plane-binding.cpp +++ b/binding-mri/plane-binding.cpp @@ -31,7 +31,7 @@ RB_METHOD(planeInitialize) { Plane *p = viewportElementInitialize(argc, argv, self); - setPrivateData(self, p, PlaneType); + setPrivateData(self, p); p->setColor(new Color); p->setTone(new Tone); @@ -64,6 +64,7 @@ planeBindingInit() INIT_TYPE(Plane); VALUE klass = rb_define_class("Plane", rb_cObject); + rb_define_alloc_func(klass, classAllocate<&PlaneType>); disposableBindingInit (klass); viewportElementBindingInit(klass); diff --git a/binding-mri/sprite-binding.cpp b/binding-mri/sprite-binding.cpp index bc62302..e29c6a4 100644 --- a/binding-mri/sprite-binding.cpp +++ b/binding-mri/sprite-binding.cpp @@ -33,7 +33,7 @@ RB_METHOD(spriteInitialize) { Sprite *s = viewportElementInitialize(argc, argv, self); - setPrivateData(self, s, SpriteType); + setPrivateData(self, s); /* Wrap property objects */ s->setSrcRect(new Rect); @@ -75,6 +75,7 @@ spriteBindingInit() INIT_TYPE(Sprite); VALUE klass = rb_define_class("Sprite", rb_cObject); + rb_define_alloc_func(klass, classAllocate<&SpriteType>); disposableBindingInit (klass); flashableBindingInit (klass); diff --git a/binding-mri/table-binding.cpp b/binding-mri/table-binding.cpp index 81152dd..8e68690 100644 --- a/binding-mri/table-binding.cpp +++ b/binding-mri/table-binding.cpp @@ -34,7 +34,7 @@ RB_METHOD(tableInitialize) Table *t = new Table(x, y, z); - setPrivateData(self, t, TableType); + setPrivateData(self, t); return self; } @@ -146,6 +146,7 @@ tableBindingInit() INIT_TYPE(Table); VALUE klass = rb_define_class("Table", rb_cObject); + rb_define_alloc_func(klass, classAllocate<&TableType>); serializableBindingInit(klass); diff --git a/binding-mri/tilemap-binding.cpp b/binding-mri/tilemap-binding.cpp index 2b5ad38..aeff10f 100644 --- a/binding-mri/tilemap-binding.cpp +++ b/binding-mri/tilemap-binding.cpp @@ -28,7 +28,7 @@ #include "binding-util.h" #include "binding-types.h" -static rb_data_type_struct TilemapAutotilesType; +rb_data_type_struct TilemapAutotilesType; RB_METHOD(tilemapAutotilesSet) { @@ -80,7 +80,7 @@ RB_METHOD(tilemapInitialize) /* Construct object */ t = new Tilemap(viewport); - setPrivateData(self, t, TilemapType); + setPrivateData(self, t); rb_iv_set(self, "viewport", viewportObj); @@ -144,6 +144,7 @@ tilemapBindingInit() initType(TilemapAutotilesType, "TilemapAutotiles", 0); VALUE klass = rb_define_class("TilemapAutotiles", rb_cObject); + rb_define_alloc_func(klass, classAllocate<&TilemapAutotilesType>); _rb_define_method(klass, "[]=", tilemapAutotilesSet); _rb_define_method(klass, "[]", tilemapAutotilesGet); @@ -151,6 +152,7 @@ tilemapBindingInit() INIT_TYPE(Tilemap); klass = rb_define_class("Tilemap", rb_cObject); + rb_define_alloc_func(klass, classAllocate<&TilemapType>); disposableBindingInit(klass); diff --git a/binding-mri/viewport-binding.cpp b/binding-mri/viewport-binding.cpp index 2406cc4..47df6be 100644 --- a/binding-mri/viewport-binding.cpp +++ b/binding-mri/viewport-binding.cpp @@ -54,7 +54,7 @@ RB_METHOD(viewportInitialize) v = new Viewport(x, y, width, height); } - setPrivateData(self, v, ViewportType); + setPrivateData(self, v); /* Wrap property objects */ v->setRect(new Rect(*v->getRect())); @@ -84,6 +84,7 @@ viewportBindingInit() INIT_TYPE(Viewport); VALUE klass = rb_define_class("Viewport", rb_cObject); + rb_define_alloc_func(klass, classAllocate<&ViewportType>); disposableBindingInit (klass); flashableBindingInit (klass); diff --git a/binding-mri/window-binding.cpp b/binding-mri/window-binding.cpp index 06402ae..b77c49c 100644 --- a/binding-mri/window-binding.cpp +++ b/binding-mri/window-binding.cpp @@ -30,7 +30,7 @@ RB_METHOD(windowInitialize) { Window *w = viewportElementInitialize(argc, argv, self); - setPrivateData(self, w, WindowType); + setPrivateData(self, w); w->setCursorRect(new Rect); wrapNilProperty(self, "windowskin"); @@ -78,6 +78,7 @@ windowBindingInit() INIT_TYPE(Window); VALUE klass = rb_define_class("Window", rb_cObject); + rb_define_alloc_func(klass, classAllocate<&WindowType>); disposableBindingInit (klass); viewportElementBindingInit(klass);