Permalink
Browse files

[core] Replace RPA of CPointers for handling returns with single

CallSingatureReturns PMC.

This decrease number of allocated GC objects by ~1M in fib.pir and
improve performance by ~11%.

This is temporary solution to bring some speed loss after PCC refactors.
Will probably removed after 2.0 release with unification of args/returns
handling.

git-svn-id: https://svn.parrot.org/parrot/trunk@42038 d31e2699-5ff4-0310-a27c-f18f2fbe73fe
  • Loading branch information...
1 parent c9d2df4 commit 3e71fe3d0d049751cd61e58a8f3d0b5326a2a592 @bacek bacek committed Oct 23, 2009
View
@@ -27,10 +27,11 @@
# please insert tab separated entries at the top of the list
+5.3 2009.10.23 bacek add CallSignatureReturns
5.2 2009.09.16 darbelo remove pic.ops
5.2 2009.08.06 dukeleto remove Random PMC
-5.1 2009.08.06 cotto remove branch_cs opcode
-5.0 2009.07.21 cotto released 1.4.0
+5.1 2009.08.06 cotto remove branch_cs opcode
+5.0 2009.07.21 cotto released 1.4.0
4.0 2009.03.17 allison released 1.0.0
3.0 2007.07.23 jonathan implementing new PBC header format
2.0 2005.11.22 leo changed PBC format (HLL_info)
View

Large diffs are not rendered by default.

Oops, something went wrong.
View
@@ -1027,7 +1027,6 @@ append_result(PARROT_INTERP, ARGIN(PMC *sig_object), ARGIN(Parrot_String type),
ASSERT_ARGS(append_result)
Parrot_String full_sig;
Parrot_PMC returns;
- Parrot_PMC return_pointer;
Parrot_PMC return_flags;
Parrot_String return_name = Parrot_str_new_constant(interp, "returns");
@@ -1039,16 +1038,12 @@ append_result(PARROT_INTERP, ARGIN(PMC *sig_object), ARGIN(Parrot_String type),
Parrot_str_concat(interp, full_sig, Parrot_str_new_constant(interp, "->"), 0);
Parrot_str_concat(interp, full_sig, type, 0);
- return_pointer = pmc_new(interp, enum_class_CPointer);
-
returns = VTABLE_get_attr_str(interp, sig_object, return_name);
if (PMC_IS_NULL(returns)) {
- returns = pmc_new(interp, enum_class_ResizablePMCArray);
+ returns = pmc_new(interp, enum_class_CallSignatureReturns);
VTABLE_set_attr_str(interp, sig_object, return_name, returns);
}
- VTABLE_set_pointer(interp, return_pointer, result);
- VTABLE_set_string_keyed_str(interp, return_pointer, sig_name, type);
- VTABLE_push_pmc(interp, returns, return_pointer);
+ VTABLE_set_pointer_keyed_int(interp, returns, VTABLE_elements(interp, returns), result);
/* Update returns_flag */
return_flags = VTABLE_get_attr_str(interp, sig_object, return_flags_name);
@@ -1057,10 +1052,22 @@ append_result(PARROT_INTERP, ARGIN(PMC *sig_object), ARGIN(Parrot_String type),
VTABLE_set_attr_str(interp, sig_object, return_flags_name, return_flags);
}
switch (Parrot_str_indexed(interp, type, 0)) {
- case 'I': VTABLE_push_integer(interp, return_flags, PARROT_ARG_INTVAL); break;
- case 'N': VTABLE_push_integer(interp, return_flags, PARROT_ARG_FLOATVAL); break;
- case 'S': VTABLE_push_integer(interp, return_flags, PARROT_ARG_STRING); break;
- case 'P': VTABLE_push_integer(interp, return_flags, PARROT_ARG_PMC); break;
+ case 'I':
+ VTABLE_push_integer(interp, return_flags, PARROT_ARG_INTVAL);
+ VTABLE_push_integer(interp, returns, PARROT_ARG_INTVAL);
+ break;
+ case 'N':
+ VTABLE_push_integer(interp, return_flags, PARROT_ARG_FLOATVAL);
+ VTABLE_push_integer(interp, returns, PARROT_ARG_FLOATVAL);
+ break;
+ case 'S':
+ VTABLE_push_integer(interp, return_flags, PARROT_ARG_STRING);
+ VTABLE_push_integer(interp, returns, PARROT_ARG_STRING);
+ break;
+ case 'P':
+ VTABLE_push_integer(interp, return_flags, PARROT_ARG_PMC);
+ VTABLE_push_integer(interp, returns, PARROT_ARG_PMC);
+ break;
default:
Parrot_ex_throw_from_c_args(interp, NULL,
EXCEPTION_INVALID_OPERATION,
@@ -0,0 +1,322 @@
+/*
+Copyright (C) 2001-2008, Parrot Foundation.
+$Id$
+
+=head1 NAME
+
+src/pmc/callsignaturereturns.pmc - resizable array for typed pointers
+
+=head1 DESCRIPTION
+
+This class stores typed pointers used to fill results in CallSignature.
+
+
+=head1 SYNOPSIS
+
+ # VTABLEs are too tight to implement something more beatyful
+
+ # Create signature
+ rets = new CallSignatureReturns
+ rets.push_pointer(&intval, 0);
+ rest.push_integer(PARROT_ARG_INTVAL);
+
+ rets.push_pointer(&floatval, 1);
+ rest.push_integer(PARROT_ARG_FLOATVAL);
+
+ rets.push_pointer(&string, 2);
+ rest.push_integer(PARROT_ARG_STRING);
+
+ rets.push_pointer(&pmc, 3);
+ rest.push_integer(PARROT_ARG_PMC);
+
+ # Fill
+ rets.set_integer_keyed_int(intval, 0);
+ rets.set_number_keyed_int(floatval, 1);
+ rets.set_string_keyed_int(string, 2);
+ rets.set_pmc_keyed_int(pmc, 3);
+
+CallSignatureReturns will behave like CPointer with autocasting values.
+
+=head2 Functions
+
+=over 4
+
+=cut
+
+*/
+
+
+/* mask off lower two bits (1 + 2 = 3) for pointer tags */
+#define TAG_BITS 3
+#define UNTAG_CELL(c) INTVAL2PTR(void *, (PTR2INTVAL(c)) & ~TAG_BITS)
+#define CELL_TYPE_MASK(c) (PTR2INTVAL(c)) & 3
+
+pmclass CallSignatureReturns auto_attrs provides array {
+ ATTR INTVAL size; /* number of stored elements */
+ ATTR void **values; /* stored pointers */
+ ATTR INTVAL resize_threshold; /* max size before array needs to be resized */
+
+/*
+
+=item C<void set_integer_native(INTVAL size)>
+
+Resizes the array to C<size> elements.
+
+=cut
+
+*/
+
+ VTABLE void set_integer_native(INTVAL size) {
+ void **values;
+ INTVAL resize_threshold;
+
+ GET_ATTR_values(INTERP, SELF, values);
+ GET_ATTR_resize_threshold(INTERP, SELF, resize_threshold);
+
+ if (!values) {
+ /* Empty. Allocate 8 elements (arbitary number) */
+ values = mem_allocate_n_zeroed_typed(8, void*);
+ SET_ATTR_values(INTERP, SELF, values);
+ SET_ATTR_size(INTERP, SELF, size);
+ SET_ATTR_resize_threshold(INTERP, SELF, 8);
+ }
+ else if (size <= resize_threshold) {
+ SET_ATTR_size(INTERP, SELF, size);
+ return;
+ }
+ else {
+ INTVAL cur = resize_threshold;
+
+ if (cur < 8192)
+ cur = size < 2 * cur ? 2 * cur : size;
+ else {
+ INTVAL needed = size - cur;
+ cur += needed + 4096;
+ cur &= ~0xfff;
+ }
+
+ values = (void**) mem_sys_realloc((void*) values, cur * sizeof (void *));
+ SET_ATTR_values(INTERP, SELF, values);
+ SET_ATTR_size(INTERP, SELF, size);
+ SET_ATTR_resize_threshold(INTERP, SELF, cur);
+ }
+ }
+
+/*
+
+=item C<INTVAL elements()>
+
+Returns the number of elements in the array.
+
+=cut
+
+*/
+
+ VTABLE INTVAL elements() {
+ INTVAL size;
+ GET_ATTR_size(INTERP, SELF, size);
+ return size;
+ }
+
+/*
+
+*/
+ VTABLE void set_pointer_keyed_int(INTVAL key, void *value) {
+ void **values;
+ INTVAL size;
+
+ GET_ATTR_size(INTERP, SELF, size);
+ if (key >= size)
+ STATICSELF.set_integer_native(key + 1);
+
+ GET_ATTR_values(INTERP, SELF, values);
+ values[key] = value;
+ }
+
+/*
+
+=item C<void push_pointer(void* value)>
+
+Push pointer to self. Increase size of storage.
+
+=cut
+
+*/
+
+ VTABLE void push_pointer(void *value) {
+ INTVAL idx = STATICSELF.elements();
+ STATICSELF.set_pointer_keyed_int(idx, value);
+ }
+
+/*
+
+=item C<void push_integer(INTVAL value)>
+
+Set type of last pushed pointer.
+
+=cut
+
+*/
+
+ VTABLE void push_integer(INTVAL type) {
+ INTVAL idx = STATICSELF.elements() - 1;
+ void **values;
+
+ PARROT_ASSERT((type >=0 && type < 4) || !"Wrong pointer type");
+
+ GET_ATTR_values(INTERP, SELF, values);
+ values[idx] = INTVAL2PTR(void *, PTR2INTVAL(UNTAG_CELL(values[idx])) | type);
+ }
+
+/*
+
+=item C<void set_integer_keyed_int(INTVAL key, INTVAL value)>
+
+=item C<void set_number_keyed_int(INTVAL key, FLOATVAL value)>
+
+=item C<void set_string_keyed_int(INTVAL key, STRING *value)>
+
+=item C<void set_pmc_keyed_int(INTVAL key, PMC *value)>
+
+Sets the value of the element at index C<key> to C<value> with casting if nessesary.
+
+=cut
+
+*/
+
+ VTABLE void set_integer_keyed_int(INTVAL key, INTVAL value) {
+ void *cell = STATICSELF.get_pointer_keyed_int(key);
+ void *ptr = UNTAG_CELL(cell);
+
+ switch((Call_bits_enum_t)CELL_TYPE_MASK(cell)) {
+ case PARROT_ARG_INTVAL:
+ *(INTVAL *)ptr = value;
+ break;
+ case PARROT_ARG_FLOATVAL:
+ *(FLOATVAL *)ptr = value;
+ break;
+ case PARROT_ARG_STRING:
+ *(STRING **)ptr = Parrot_str_from_int(INTERP, value);
+ break;
+ case PARROT_ARG_PMC:
+ *(PMC **)ptr = get_integer_pmc(INTERP, value);
+ break;
+ default:
+ PARROT_ASSERT(!"Impossible type");
+ }
+ }
+
+ VTABLE void set_number_keyed_int(INTVAL key, FLOATVAL value) {
+ void *cell = STATICSELF.get_pointer_keyed_int(key);
+ void *ptr = UNTAG_CELL(cell);
+
+ switch((Call_bits_enum_t)CELL_TYPE_MASK(cell)) {
+ case PARROT_ARG_INTVAL:
+ *(INTVAL *)ptr = value;
+ break;
+ case PARROT_ARG_FLOATVAL:
+ *(FLOATVAL *)ptr = value;
+ break;
+ case PARROT_ARG_STRING:
+ *(STRING **)ptr = Parrot_str_from_num(INTERP, value);
+ break;
+ case PARROT_ARG_PMC:
+ *(PMC **)ptr = get_number_pmc(INTERP, value);
+ break;
+ default:
+ PARROT_ASSERT(!"Impossible type");
+ }
+ }
+
+ VTABLE void set_string_keyed_int(INTVAL key, STRING *value) {
+ void *cell = STATICSELF.get_pointer_keyed_int(key);
+ void *ptr = UNTAG_CELL(cell);
+
+ switch((Call_bits_enum_t)CELL_TYPE_MASK(cell)) {
+ case PARROT_ARG_INTVAL:
+ *(INTVAL *)ptr = Parrot_str_to_int(INTERP, value);
+ break;
+ case PARROT_ARG_FLOATVAL:
+ *(FLOATVAL *)ptr = Parrot_str_to_num(INTERP, value);
+ break;
+ case PARROT_ARG_STRING:
+ *(STRING **)ptr = value;
+ break;
+ case PARROT_ARG_PMC:
+ *(PMC **)ptr = get_string_pmc(INTERP, value);
+ break;
+ default:
+ PARROT_ASSERT(!"Impossible type");
+ }
+ }
+
+ VTABLE void set_pmc_keyed_int(INTVAL key, PMC *value) {
+ void *cell = STATICSELF.get_pointer_keyed_int(key);
+ void *ptr = UNTAG_CELL(cell);
+
+ switch((Call_bits_enum_t)CELL_TYPE_MASK(cell)) {
+ case PARROT_ARG_INTVAL:
+ *(INTVAL *)ptr = VTABLE_get_integer(INTERP, value);
+ break;
+ case PARROT_ARG_FLOATVAL:
+ *(FLOATVAL *)ptr = VTABLE_get_number(INTERP, value);
+ break;
+ case PARROT_ARG_STRING:
+ *(STRING **)ptr = VTABLE_get_string(INTERP, value);
+ break;
+ case PARROT_ARG_PMC:
+ *(PMC **)ptr = value;
+ break;
+ default:
+ PARROT_ASSERT(!"Impossible type");
+ }
+ }
+
+/*
+
+*/
+ VTABLE STRING *get_string_keyed_int(INTVAL key) {
+ void *cell = STATICSELF.get_pointer_keyed_int(key);
+ void *ptr = UNTAG_CELL(cell);
+ return (STRING *)ptr;
+ }
+
+/*
+
+=item C<void *get_pointer_keyed_int(INTVAL key)>
+
+Get raw pointer for result.
+
+=cut
+
+*/
+
+ VTABLE void *get_pointer_keyed_int(INTVAL key) {
+ void **values;
+ INTVAL size;
+
+ GET_ATTR_size(INTERP, SELF, size);
+ PARROT_ASSERT((key < size) || !"Wrong index");
+
+ GET_ATTR_values(INTERP, SELF, values);
+ return values[key];
+ }
+}
+/*
+
+=back
+
+=head1 SEE ALSO
+
+F<docs/pdds/pdd03_calling_conventions.pod>.
+
+=cut
+
+*/
+
+/*
+ * Local variables:
+ * c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */
Binary file not shown.
View
Binary file not shown.
View
Binary file not shown.

0 comments on commit 3e71fe3

Please sign in to comment.