[cairo-commit] 3 commits - perf/README util/cairo-trace
Chris Wilson
ickle at kemper.freedesktop.org
Mon Jun 8 11:02:55 PDT 2009
perf/README | 2
util/cairo-trace/cairo-trace.in | 5 ++
util/cairo-trace/trace.c | 89 ++++++++++++++++++++++++++++------------
3 files changed, 69 insertions(+), 27 deletions(-)
New commits:
commit 015df191ba947e714285145c3a4ead198ba0d07e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Jun 8 17:40:16 2009 +0100
[trace] Prevent overflowing the operand stack when recreating objects
Objects like cairo_scaled_font_t may return a reference to a previously
defined scaled-font instead of creating a new token each time. This caused
cairo-trace to overflow its operand stack by pushing a new instance of the
old token every time. Modify the tracer such that a font token can only
appear once on the stack -- for font-faces we remove the old operand and
for scaled-fonts we simply pop, chosen to reflect expected usage.
diff --git a/util/cairo-trace/trace.c b/util/cairo-trace/trace.c
index 4826e99..db7a251 100644
--- a/util/cairo-trace/trace.c
+++ b/util/cairo-trace/trace.c
@@ -885,38 +885,61 @@ static void
_push_operand (enum operand_type t, const void *ptr)
{
Object *obj = _get_object (t, ptr);
+
+ if (current_stack_depth ==
+ sizeof (current_object) / sizeof (current_object[0]))
+ {
+ int n;
+
+ fprintf (stderr, "Operand stack overflow!\n");
+ for (n = 0; n < current_stack_depth; n++) {
+ obj = current_object[n];
+
+ fprintf (stderr, " [%3d] = %s%ld\n",
+ n, obj->type->op_code, obj->token);
+ }
+
+ abort ();
+ }
+
obj->operand = current_stack_depth;
current_object[current_stack_depth++] = obj;
}
static void
-_object_undef (void *ptr)
+_object_remove (Object *obj)
{
- Object *obj = ptr;
-
- if (_write_lock ()) {
- if (obj->operand != -1) {
- if (obj->operand == current_stack_depth - 1) {
- _trace_printf ("pop %% %s%ld destroyed\n",
- obj->type->op_code, obj->token);
- } else if (obj->operand == current_stack_depth - 2) {
- _exch_operands ();
- _trace_printf ("exch pop %% %s%ld destroyed\n",
- obj->type->op_code, obj->token);
- } else {
- int n;
+ if (obj->operand != -1) {
+ if (obj->operand == current_stack_depth - 1) {
+ _trace_printf ("pop %% %s%ld destroyed\n",
+ obj->type->op_code, obj->token);
+ } else if (obj->operand == current_stack_depth - 2) {
+ _exch_operands ();
+ _trace_printf ("exch pop %% %s%ld destroyed\n",
+ obj->type->op_code, obj->token);
+ } else {
+ int n;
- _trace_printf ("%d -1 roll pop %% %s%ld destroyed\n",
- current_stack_depth - obj->operand,
- obj->type->op_code, obj->token);
+ _trace_printf ("%d -1 roll pop %% %s%ld destroyed\n",
+ current_stack_depth - obj->operand,
+ obj->type->op_code, obj->token);
- for (n = obj->operand; n < current_stack_depth - 1; n++) {
- current_object[n] = current_object[n+1];
- current_object[n]->operand = n;
- }
+ for (n = obj->operand; n < current_stack_depth - 1; n++) {
+ current_object[n] = current_object[n+1];
+ current_object[n]->operand = n;
}
- current_stack_depth--;
}
+ current_stack_depth--;
+ }
+}
+
+static void
+_object_undef (void *ptr)
+{
+ Object *obj = ptr;
+
+ if (_write_lock ()) {
+ _object_remove (obj);
if (obj->defined) {
_trace_printf ("/%s%ld undef\n",
@@ -2722,11 +2745,16 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
_emit_font_options (options);
- _trace_printf (" scaled-font dup /sf%ld exch def\n",
- scaled_font_id);
+ if (_get_object (SCALED_FONT, ret)->defined) {
+ _trace_printf (" scaled-font pop %% sf%ld\n",
+ scaled_font_id);
+ } else {
+ _trace_printf (" scaled-font dup /sf%ld exch def\n",
+ scaled_font_id);
+ _push_operand (SCALED_FONT, ret);
- _get_object (SCALED_FONT, ret)->defined = true;
- _push_operand (SCALED_FONT, ret);
+ _get_object (SCALED_FONT, ret)->defined = true;
+ }
_write_unlock ();
}
@@ -3470,8 +3498,13 @@ cairo_ft_font_face_create_for_pattern (FcPattern *pattern)
_emit_line_info ();
if (pattern != NULL && _write_lock ()) {
+ Object *obj;
FcChar8 *parsed;
+ obj = _get_object (FONT_FACE, ret);
+ if (obj->operand != -1)
+ _object_remove (obj);
+
parsed = DLCALL (FcNameUnparse, pattern);
_trace_printf ("dict\n"
" /type 42 set\n"
@@ -3523,6 +3556,10 @@ cairo_ft_font_face_create_for_ft_face (FT_Face face, int load_flags)
_emit_line_info ();
if (_write_lock ()) {
+ obj = _get_object (FONT_FACE, ret);
+ if (obj->operand != -1)
+ _object_remove (obj);
+
_trace_printf ("dict\n"
" /type 42 set\n"
" /source ");
commit 09492288b33c36093e50d39e4e7e632ab659a0e2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Jun 8 17:38:14 2009 +0100
[trace] Option to re-enable mark-dirty
Applications such as swfdec have a strictly correct use of mark-dirty and
so we need an option to re-enable mark-dirty tracing in conjunction with
--profile.
diff --git a/util/cairo-trace/cairo-trace.in b/util/cairo-trace/cairo-trace.in
index 8a1e1b8..16cdad6 100644
--- a/util/cairo-trace/cairo-trace.in
+++ b/util/cairo-trace/cairo-trace.in
@@ -20,6 +20,7 @@ Whatever else happens is driven by its argument:
--no-file - Disable the creation of an output file. Outputs to the
terminal instead.
--no-callers - Do not lookup the caller address/symbol/line whilst tracing.
+ --mark-dirty - Record image data for cairo_mark_dirty() [default]
--no-mark-dirty - Do not record image data for cairo_mark_dirty()
--compress - Compress the output with LZMA
--profile - Combine --no-callers and --no-mark-dirty and --compress
@@ -47,6 +48,10 @@ while test $skip -eq 1; do
skip=1
nocallers=1
;;
+ --mark-dirty)
+ skip=1
+ nomarkdirty=
+ ;;
--no-mark-dirty)
skip=1
nomarkdirty=1
commit 39bac6edddb8913d07fb25f14f088967ca846a78
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Jun 8 11:52:56 2009 +0100
[perf] Mention cairo-perf-trace early on in the README
diff --git a/perf/README b/perf/README
index efd9e40..abf0687 100644
--- a/perf/README
+++ b/perf/README
@@ -184,7 +184,7 @@ How to benchmark traces
-----------------------
Using cairo-trace you can record the exact sequence of graphic operations
made by an application and replay them later. These traces can then be
-used to benchmark the various backends and patches.
+used by cairo-perf-trace to benchmark the various backends and patches.
To record a trace:
$ cairo-trace --no-mark-dirty --no-callers $APPLICATION [$ARGV]
More information about the cairo-commit
mailing list