summaryrefslogtreecommitdiff
path: root/plugins/dex
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2020-01-27 18:48:58 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2020-01-27 18:48:58 (GMT)
commitc1ca03be00a4e975f89d30edfb72b57fb5612282 (patch)
tree4884513252458a261eb1290c93748b2bbbd98ff8 /plugins/dex
parent1b3887c5609831bc2aee2f00f6a4d31d7406a225 (diff)
Created a huge optimization for the Dex format loading.
Diffstat (limited to 'plugins/dex')
-rw-r--r--plugins/dex/class.c143
-rw-r--r--plugins/dex/class.h4
-rw-r--r--plugins/dex/pool.c45
3 files changed, 134 insertions, 58 deletions
diff --git a/plugins/dex/class.c b/plugins/dex/class.c
index dafa984..d549014 100644
--- a/plugins/dex/class.c
+++ b/plugins/dex/class.c
@@ -222,11 +222,7 @@ GDexClass *g_dex_class_new(GDexFormat *format, const class_def_item *def)
uleb128_t index; /* Conservation du dernier id */
uleb128_t i; /* Boucle de parcours */
GDexField *field; /* Champ chargé */
- GDexPool *pool; /* Table de ressources */
- GDataType *ctype; /* Type créé par la classe */
- GBinFormat *base; /* Autre version du format */
GDexMethod *method; /* Méthode chargée */
- GBinRoutine *routine; /* Version interne de méthode */
result = g_object_new(G_TYPE_DEX_CLASS, NULL);
@@ -292,16 +288,6 @@ GDexClass *g_dex_class_new(GDexFormat *format, const class_def_item *def)
* Chargement des méthodes de classe.
*/
- pool = g_dex_format_get_pool(format);
-
- ctype = g_dex_pool_get_type_(pool, def->class_idx);
-
- g_object_unref(G_OBJECT(pool));
-
- if (ctype == NULL) goto gdcn_unknown_type;
-
- base = G_BIN_FORMAT(format);
-
index = 0;
result->dmethods_count = data.direct_methods_size;
@@ -314,18 +300,6 @@ GDexClass *g_dex_class_new(GDexFormat *format, const class_def_item *def)
result->direct_methods[i] = method;
- /* Ajout à la liste des symboles */
- if (g_dex_method_has_dex_body(method))
- {
- routine = g_dex_method_get_routine(method);
-
- g_object_ref(G_OBJECT(ctype));
- g_binary_routine_set_namespace(routine, ctype, strdup("."));
-
- g_binary_format_add_symbol(base, G_BIN_SYMBOL(routine));
-
- }
-
}
index = 0;
@@ -340,32 +314,14 @@ GDexClass *g_dex_class_new(GDexFormat *format, const class_def_item *def)
result->virtual_methods[i] = method;
- /* Ajout à la liste des symboles */
- if (g_dex_method_has_dex_body(method))
- {
- routine = g_dex_method_get_routine(method);
-
- g_object_ref(G_OBJECT(ctype));
- g_binary_routine_set_namespace(routine, ctype, strdup("."));
-
- g_binary_format_add_symbol(base, G_BIN_SYMBOL(routine));
-
- }
-
}
- g_object_unref(G_OBJECT(ctype));
-
gdcn_done:
return result;
gdcn_bad_method:
- g_object_unref(G_OBJECT(ctype));
-
- gdcn_unknown_type:
-
gdcn_bad_field:
gdcn_bad_item:
@@ -379,7 +335,7 @@ GDexClass *g_dex_class_new(GDexFormat *format, const class_def_item *def)
/******************************************************************************
* *
-* Paramètres : class = informations chargées à consulter. *
+* Paramètres : class = informations chargées à consulter. *
* *
* Description : Fournit la définition brute d'une classe. *
* *
@@ -398,7 +354,7 @@ const class_def_item *g_dex_class_get_definition(const GDexClass *class)
/******************************************************************************
* *
-* Paramètres : class = informations chargées à consulter. *
+* Paramètres : class = informations chargées à consulter. *
* *
* Description : Fournit la définition brute des données d'une classe. *
* *
@@ -660,6 +616,101 @@ GDexMethod *g_dex_class_get_method(const GDexClass *class, bool virtual, size_t
/******************************************************************************
* *
+* Paramètres : class = informations chargées à consulter. *
+* symbols = liste de symboles complétée. [OUT] *
+* count = taille de cette liste. [OUT] *
+* *
+* Description : Etablit une liste de tous les symboles d'une classe. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_dex_class_get_collect_symbols(const GDexClass *class, GBinSymbol ***symbols, size_t *count)
+{
+ bool result; /* Bilan à retourner */
+ GDexPool *pool; /* Table de ressources */
+ GDataType *ctype; /* Type créé par la classe */
+ size_t slots_used; /* Compteur d'utilisations */
+ size_t i; /* Boucle de parcours */
+ GDexMethod *method; /* Méthode chargée */
+ GBinRoutine *routine; /* Version interne de méthode */
+
+ result = false;
+
+ /* Contexte des méthodes */
+
+ pool = g_dex_format_get_pool(class->format);
+
+ ctype = g_dex_pool_get_type_(pool, class->definition.class_idx);
+
+ g_object_unref(G_OBJECT(pool));
+
+ if (ctype == NULL) goto unknown_type;
+
+ /* Intégration des méthodes */
+
+ *symbols = realloc(*symbols, (*count + class->dmethods_count + class->vmethods_count) * sizeof(GBinSymbol *));
+
+ result = true;
+
+ slots_used = 0;
+
+ for (i = 0; i < class->dmethods_count; i++)
+ {
+ method = class->direct_methods[i];
+
+ if (g_dex_method_has_dex_body(method))
+ {
+ routine = g_dex_method_get_routine(method);
+
+ g_object_ref(G_OBJECT(ctype));
+ g_binary_routine_set_namespace(routine, ctype, strdup("."));
+
+ (*symbols)[*count + slots_used] = G_BIN_SYMBOL(routine);
+ slots_used++;
+
+ }
+
+ }
+
+ *count += slots_used;
+
+ slots_used = 0;
+
+ for (i = 0; i < class->vmethods_count; i++)
+ {
+ method = class->virtual_methods[i];
+
+ if (g_dex_method_has_dex_body(method))
+ {
+ routine = g_dex_method_get_routine(method);
+
+ g_object_ref(G_OBJECT(ctype));
+ g_binary_routine_set_namespace(routine, ctype, strdup("."));
+
+ (*symbols)[*count + slots_used] = G_BIN_SYMBOL(routine);
+ slots_used++;
+
+ }
+
+ }
+
+ *count += slots_used;
+
+ g_object_unref(G_OBJECT(ctype));
+
+ unknown_type:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : class = informations chargées à consulter. *
* format = format permettant d'obtenir une adresse complète. *
* *
diff --git a/plugins/dex/class.h b/plugins/dex/class.h
index cae4a5a..a7874a7 100644
--- a/plugins/dex/class.h
+++ b/plugins/dex/class.h
@@ -50,7 +50,6 @@ typedef struct _GDexClass GDexClass;
typedef struct _GDexClassClass GDexClassClass;
-
/* Détermine le type d'une classe issue du code source. */
GType g_dex_class_get_type(void);
@@ -84,6 +83,9 @@ size_t g_dex_class_count_methods(const GDexClass *, bool);
/* Fournit une méthode chargée correspondant à un type donné. */
GDexMethod *g_dex_class_get_method(const GDexClass *, bool, size_t);
+/* Etablit une liste de tous les symboles d'une classe. */
+bool g_dex_class_get_collect_symbols(const GDexClass *, GBinSymbol ***, size_t *);
+
/* Intègre la méthode en tant que portion de code. */
void g_dex_class_include_as_portion(const GDexClass *, GExeFormat *);
diff --git a/plugins/dex/pool.c b/plugins/dex/pool.c
index c24617a..d800e8f 100644
--- a/plugins/dex/pool.c
+++ b/plugins/dex/pool.c
@@ -251,6 +251,11 @@ bool g_dex_pool_load_all_string_symbols(GDexPool *pool, wgroup_id_t gid, GtkStat
gtk_status_stack_remove_activity(status, msg);
+ /* Insertion en tant que symboles */
+
+ if (result)
+ result = g_binary_format_add_symbols(G_BIN_FORMAT(pool->format), pool->strings, count);
+
return result;
}
@@ -367,7 +372,6 @@ GBinSymbol *g_dex_pool_get_string_symbol(GDexPool *pool, uint32_t index)
const char *string; /* Chaîne de caractères liée */
GBinFormat *base; /* Autre version du format */
GBinSymbol *new; /* Nouveau symbol créé */
- bool inserted; /* Bilan d'une insertion */
result = NULL;
@@ -385,16 +389,10 @@ GBinSymbol *g_dex_pool_get_string_symbol(GDexPool *pool, uint32_t index)
new = g_string_symbol_new_read_only(base, &range, SET_MUTF_8);
- g_string_symbol_build_label(G_STR_SYMBOL(new), base);
-
- g_object_ref(G_OBJECT(new));
- inserted = g_binary_format_add_symbol(base, new);
-
- if (inserted)
- pool->strings[index] = new;
+ if (new != NULL)
+ g_string_symbol_build_label(G_STR_SYMBOL(new), base);
- else
- g_object_unref(G_OBJECT(new));
+ pool->strings[index] = new;
}
@@ -1175,10 +1173,14 @@ bool g_dex_pool_load_all_classes(GDexPool *pool, wgroup_id_t gid, GtkStatusStack
uint32_t run_size; /* Volume réparti par exécution*/
GWorkQueue *queue; /* Gestionnaire de différés */
activity_id_t msg; /* Message de progression */
- guint i; /* Boucle de parcours */
+ guint i; /* Boucle de parcours #1 */
uint32_t begin; /* Début de bloc de traitement */
uint32_t end; /* Fin d'un bloc de traitement */
GDexLoading *loading; /* Tâche de chargement à lancer*/
+ GBinSymbol **symbols; /* Symboles présents à injecter*/
+ size_t scount; /* Quantité de ces symboles */
+ uint32_t j; /* Boucle de parcours #2 */
+ size_t k; /* Boucle de parcours #3 */
result = true;
@@ -1216,6 +1218,27 @@ bool g_dex_pool_load_all_classes(GDexPool *pool, wgroup_id_t gid, GtkStatusStack
gtk_status_stack_remove_activity(status, msg);
+ /* Insertion en tant que symboles */
+
+ if (result)
+ {
+ symbols = NULL;
+ scount = 0;
+
+ for (j = 0; j < count && result; j++)
+ result = g_dex_class_get_collect_symbols(pool->classes[j], &symbols, &scount);
+
+ if (result)
+ result = g_binary_format_add_symbols(G_BIN_FORMAT(pool->format), symbols, count);
+
+ for (k = 0; k < scount; k++)
+ g_object_unref(symbols[k]);
+
+ if (symbols != NULL)
+ free(symbols);
+
+ }
+
return result;
}