Signed-off-by: Vegard Nossum <[email protected]>
---
include/vm/field.h | 4 +-
vm/class.c | 135 +++++++++++++++++++++++++++++++++++++++++----------
vm/field.c | 11 +----
3 files changed, 112 insertions(+), 38 deletions(-)
diff --git a/include/vm/field.h b/include/vm/field.h
index 4a5a557..20bfc0f 100644
--- a/include/vm/field.h
+++ b/include/vm/field.h
@@ -25,8 +25,8 @@ struct vm_field {
int vm_field_init(struct vm_field *vmf,
struct vm_class *vmc, unsigned int field_index);
-void vm_field_init_nonstatic(struct vm_field *vmf, unsigned int offset);
-int vm_field_init_static(struct vm_field *vmf, unsigned int offset);
+void vm_field_init_nonstatic(struct vm_field *vmf);
+int vm_field_init_static(struct vm_field *vmf);
static inline bool vm_field_is_static(const struct vm_field *vmf)
{
diff --git a/vm/class.c b/vm/class.c
index 8cb6ebb..f35fba5 100644
--- a/vm/class.c
+++ b/vm/class.c
@@ -37,6 +37,8 @@
#include "cafebabe/method_info.h"
#include "cafebabe/stream.h"
+#include "lib/string.h"
+
#include "vm/class.h"
#include "vm/classloader.h"
#include "vm/die.h"
@@ -46,8 +48,8 @@
#include "vm/itable.h"
#include "vm/method.h"
#include "vm/object.h"
+#include "vm/stdlib.h"
#include "vm/thread.h"
-#include "lib/string.h"
#include "vm/vm.h"
#include "jit/exception.h"
@@ -141,6 +143,64 @@ static int vm_class_link_common(struct vm_class *vmc)
return 0;
}
+/*
+ * This is used for grouping fields by their type, so that we can:
+ *
+ * 1. put reference types first (improves GC)
+ * 2. sort the rest of the fields by size (improves object layout)
+ */
+struct field_bucket {
+ unsigned int nr;
+ struct vm_field **fields;
+};
+
+static void bucket_order_fields(struct field_bucket *bucket,
+ unsigned int size, unsigned int *offset)
+{
+ unsigned int tmp_offset = *offset;
+
+ for (unsigned int i = 0; i < bucket->nr; ++i) {
+ struct vm_field *vmf = bucket->fields[i];
+
+ vmf->offset = tmp_offset;
+ tmp_offset += size;
+ }
+
+ *offset = tmp_offset;
+}
+
+static void buckets_order_fields(struct field_bucket buckets[VM_TYPE_MAX],
+ unsigned int *ref_size, unsigned int *size)
+{
+ unsigned int offset = *size;
+
+ /* We need to align here, because offset might be non-zero from the
+ * parent class. */
+ offset = ALIGN(offset, sizeof(void *));
+ bucket_order_fields(&buckets[J_REFERENCE], sizeof(void *), &offset);
+
+ /* Align with 8-byte boundary here. We don't need to align anything
+ * after this, since we _know_ e.g. that after 8-byte fields, we will
+ * always be 8-byte aligned, which is also always 4-byte aligned. */
+ offset = ALIGN(offset, 8);
+
+ bucket_order_fields(&buckets[J_DOUBLE], 8, &offset);
+ bucket_order_fields(&buckets[J_LONG], 8, &offset);
+
+ bucket_order_fields(&buckets[J_FLOAT], 4, &offset);
+ bucket_order_fields(&buckets[J_INT], 4, &offset);
+
+ /* XXX: Should be size = 2 */
+ bucket_order_fields(&buckets[J_SHORT], 4, &offset);
+ bucket_order_fields(&buckets[J_CHAR], 4, &offset);
+
+ /* XXX: Should be size = 1 */
+ bucket_order_fields(&buckets[J_BYTE], 4, &offset);
+ bucket_order_fields(&buckets[J_BOOLEAN], 4, &offset);
+
+ *size = offset;
+}
+
int vm_class_link(struct vm_class *vmc, const struct cafebabe_class *class)
{
int err;
@@ -254,55 +314,76 @@ int vm_class_link(struct vm_class *vmc, const struct
cafebabe_class *class)
return -1;
}
- unsigned int offset;
- unsigned int static_offset;
+ for (uint16_t i = 0; i < class->fields_count; ++i) {
+ struct vm_field *vmf = &vmc->fields[i];
+
+ if (vm_field_init(vmf, vmc, i)) {
+ NOT_IMPLEMENTED;
+ return -1;
+ }
+ }
if (vmc->super) {
- offset = vmc->super->object_size;
- static_offset = vmc->super->static_size;
+ vmc->static_size = vmc->super->static_size;
+ vmc->object_size = vmc->super->object_size;
} else {
- offset = 0;
- static_offset = 0;
+ vmc->static_size = 0;
+ vmc->object_size = 0;
}
- unsigned int static_size = 0;
- unsigned int object_size = 0;
+ struct field_bucket field_buckets[2][VM_TYPE_MAX];
+ for (unsigned int i = 0; i < VM_TYPE_MAX; ++i) {
+ field_buckets[0][i].nr = 0;
+ field_buckets[1][i].nr = 0;
+ }
+ /* Count the number of fields for each bucket */
for (uint16_t i = 0; i < class->fields_count; ++i) {
struct vm_field *vmf = &vmc->fields[i];
+ unsigned int stat = vm_field_is_static(vmf) ? 0 : 1;
+ enum vm_type type = str_to_type(vmf->type);
+ struct field_bucket *bucket = &field_buckets[stat][type];
- if (vm_field_init(vmf, vmc, i)) {
- NOT_IMPLEMENTED;
- return -1;
+ ++bucket->nr;
+ }
+
+ /* Allocate enough space in each bucket */
+ for (unsigned int i = 0; i < VM_TYPE_MAX; ++i) {
+ for (unsigned int j = 0; j < 2; ++j) {
+ struct field_bucket *bucket = &field_buckets[j][i];
+
+ bucket->fields = malloc(bucket->nr *
sizeof(*bucket->fields));
+ bucket->nr = 0;
}
+ }
- if (vm_field_is_static(vmf))
- static_size += 8;
- else
- object_size += 8;
+ /* Place the fields in the buckets */
+ for (uint16_t i = 0; i < class->fields_count; ++i) {
+ struct vm_field *vmf = &vmc->fields[i];
+ unsigned int stat = vm_field_is_static(vmf) ? 0 : 1;
+ enum vm_type type = str_to_type(vmf->type);
+ struct field_bucket *bucket = &field_buckets[stat][type];
+
+ bucket->fields[bucket->nr++] = vmf;
}
- /* XXX: only static fields, right size, etc. */
- vmc->static_size = static_offset + static_size;
- vmc->static_values = malloc(vmc->static_size);
+ unsigned int tmp;
+ buckets_order_fields(field_buckets[0], &tmp, &vmc->static_size);
+ buckets_order_fields(field_buckets[1], &tmp, &vmc->object_size);
- vmc->object_size = offset + object_size;
+ /* XXX: only static fields, right size, etc. */
+ vmc->static_values = zalloc(vmc->static_size);
for (uint16_t i = 0; i < class->fields_count; ++i) {
struct vm_field *vmf = &vmc->fields[i];
if (vm_field_is_static(vmf)) {
- if (vm_field_init_static(vmf, static_offset)) {
+ if (vm_field_init_static(vmf)) {
NOT_IMPLEMENTED;
return -1;
}
-
- /* XXX: Same as below */
- static_offset += 8;
} else {
- vm_field_init_nonstatic(vmf, offset);
- /* XXX: Do field reordering and use the right sizes */
- offset += 8;
+ vm_field_init_nonstatic(vmf);
}
}
diff --git a/vm/field.c b/vm/field.c
index 2d012b6..babc286 100644
--- a/vm/field.c
+++ b/vm/field.c
@@ -54,24 +54,17 @@ int vm_field_init(struct vm_field *vmf,
return 0;
}
-void vm_field_init_nonstatic(struct vm_field *vmf, unsigned int offset)
+void vm_field_init_nonstatic(struct vm_field *vmf)
{
- vmf->offset = offset;
}
-int vm_field_init_static(struct vm_field *vmf, unsigned int offset)
+int vm_field_init_static(struct vm_field *vmf)
{
- vmf->offset = offset;
-
const struct vm_class *vmc = vmf->class;
const struct cafebabe_class *class = vmc->class;
const struct cafebabe_field_info *field
= &class->fields[vmf->field_index];
- /* XXX: Might have to change this when our fields have different
- * sizes internally as well. */
- *(unsigned long *) &vmc->static_values[offset] = 0;
-
unsigned int constant_value_index = 0;
if (cafebabe_attribute_array_get(&field->attributes,
"ConstantValue", class, &constant_value_index))
--
1.6.0.6
------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now. http://p.sf.net/sfu/bobj-july
_______________________________________________
Jatovm-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jatovm-devel