2 * Copyright 2001-2003 Ximian, Inc
3 * Copyright 2003-2010 Novell, Inc.
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 #include "sgen-protocol.h"
27 #ifdef SGEN_BINARY_PROTOCOL
29 /* If not null, dump binary protocol to this file */
30 static FILE *binary_protocol_file
= NULL
;
32 #define BINARY_PROTOCOL_BUFFER_SIZE (65536 - 2 * 8)
34 typedef struct _BinaryProtocolBuffer BinaryProtocolBuffer
;
35 struct _BinaryProtocolBuffer
{
36 BinaryProtocolBuffer
*next
;
38 unsigned char buffer
[BINARY_PROTOCOL_BUFFER_SIZE
];
41 static BinaryProtocolBuffer
*binary_protocol_buffers
= NULL
;
42 LOCK_DECLARE (binary_protocol_mutex
);
45 binary_protocol_flush_buffers_rec (BinaryProtocolBuffer
*buffer
)
50 binary_protocol_flush_buffers_rec (buffer
->next
);
52 g_assert (buffer
->index
> 0);
53 fwrite (buffer
->buffer
, 1, buffer
->index
, binary_protocol_file
);
55 mono_sgen_free_os_memory (buffer
, sizeof (BinaryProtocolBuffer
));
59 binary_protocol_flush_buffers (void)
61 if (!binary_protocol_file
)
64 binary_protocol_flush_buffers_rec (binary_protocol_buffers
);
65 binary_protocol_buffers
= NULL
;
68 static BinaryProtocolBuffer
*
69 binary_protocol_get_buffer (int length
)
71 BinaryProtocolBuffer
*buffer
, *new_buffer
;
74 buffer
= binary_protocol_buffers
;
75 if (buffer
&& buffer
->index
+ length
<= BINARY_PROTOCOL_BUFFER_SIZE
)
78 new_buffer
= mono_sgen_alloc_os_memory (sizeof (BinaryProtocolBuffer
), TRUE
);
79 new_buffer
->next
= buffer
;
80 new_buffer
->index
= 0;
82 if (InterlockedCompareExchangePointer ((void**)&binary_protocol_buffers
, new_buffer
, buffer
) != buffer
) {
83 mono_sgen_free_os_memory (new_buffer
, sizeof (BinaryProtocolBuffer
));
92 protocol_entry (unsigned char type
, gpointer data
, int size
)
95 BinaryProtocolBuffer
*buffer
;
97 if (!binary_protocol_file
)
101 buffer
= binary_protocol_get_buffer (size
+ 1);
103 index
= buffer
->index
;
104 if (index
+ 1 + size
> BINARY_PROTOCOL_BUFFER_SIZE
)
107 if (InterlockedCompareExchange (&buffer
->index
, index
+ 1 + size
, index
) != index
)
108 goto retry_same_buffer
;
110 buffer
->buffer
[index
++] = type
;
111 memcpy (buffer
->buffer
+ index
, data
, size
);
114 g_assert (index
<= BINARY_PROTOCOL_BUFFER_SIZE
);
118 binary_protocol_collection (int generation
)
120 SGenProtocolCollection entry
= { generation
};
121 binary_protocol_flush_buffers ();
122 protocol_entry (SGEN_PROTOCOL_COLLECTION
, &entry
, sizeof (SGenProtocolCollection
));
126 binary_protocol_alloc (gpointer obj
, gpointer vtable
, int size
)
128 SGenProtocolAlloc entry
= { obj
, vtable
, size
};
129 protocol_entry (SGEN_PROTOCOL_ALLOC
, &entry
, sizeof (SGenProtocolAlloc
));
133 binary_protocol_alloc_pinned (gpointer obj
, gpointer vtable
, int size
)
135 SGenProtocolAlloc entry
= { obj
, vtable
, size
};
136 protocol_entry (SGEN_PROTOCOL_ALLOC_PINNED
, &entry
, sizeof (SGenProtocolAlloc
));
140 binary_protocol_alloc_degraded (gpointer obj
, gpointer vtable
, int size
)
142 SGenProtocolAlloc entry
= { obj
, vtable
, size
};
143 protocol_entry (SGEN_PROTOCOL_ALLOC_DEGRADED
, &entry
, sizeof (SGenProtocolAlloc
));
147 binary_protocol_copy (gpointer from
, gpointer to
, gpointer vtable
, int size
)
149 SGenProtocolCopy entry
= { from
, to
, vtable
, size
};
150 protocol_entry (SGEN_PROTOCOL_COPY
, &entry
, sizeof (SGenProtocolCopy
));
154 binary_protocol_pin (gpointer obj
, gpointer vtable
, int size
)
156 SGenProtocolPin entry
= { obj
, vtable
, size
};
157 protocol_entry (SGEN_PROTOCOL_PIN
, &entry
, sizeof (SGenProtocolPin
));
161 binary_protocol_mark (gpointer obj
, gpointer vtable
, int size
)
163 SGenProtocolMark entry
= { obj
, vtable
, size
};
164 protocol_entry (SGEN_PROTOCOL_MARK
, &entry
, sizeof (SGenProtocolMark
));
168 binary_protocol_wbarrier (gpointer ptr
, gpointer value
, gpointer value_vtable
)
170 SGenProtocolWBarrier entry
= { ptr
, value
, value_vtable
};
171 protocol_entry (SGEN_PROTOCOL_WBARRIER
, &entry
, sizeof (SGenProtocolWBarrier
));
175 binary_protocol_global_remset (gpointer ptr
, gpointer value
, gpointer value_vtable
)
177 SGenProtocolGlobalRemset entry
= { ptr
, value
, value_vtable
};
178 protocol_entry (SGEN_PROTOCOL_GLOBAL_REMSET
, &entry
, sizeof (SGenProtocolGlobalRemset
));
182 binary_protocol_ptr_update (gpointer ptr
, gpointer old_value
, gpointer new_value
, gpointer vtable
, int size
)
184 SGenProtocolPtrUpdate entry
= { ptr
, old_value
, new_value
, vtable
, size
};
185 protocol_entry (SGEN_PROTOCOL_PTR_UPDATE
, &entry
, sizeof (SGenProtocolPtrUpdate
));
189 binary_protocol_cleanup (gpointer ptr
, gpointer vtable
, int size
)
191 SGenProtocolCleanup entry
= { ptr
, vtable
, size
};
192 protocol_entry (SGEN_PROTOCOL_CLEANUP
, &entry
, sizeof (SGenProtocolCleanup
));
196 binary_protocol_empty (gpointer start
, int size
)
198 SGenProtocolEmpty entry
= { start
, size
};
199 protocol_entry (SGEN_PROTOCOL_EMPTY
, &entry
, sizeof (SGenProtocolEmpty
));
203 binary_protocol_thread_restart (gpointer thread
)
205 SGenProtocolThreadRestart entry
= { thread
};
206 protocol_entry (SGEN_PROTOCOL_THREAD_RESTART
, &entry
, sizeof (SGenProtocolThreadRestart
));
211 binary_protocol_thread_register (gpointer thread
)
213 SGenProtocolThreadRegister entry
= { thread
};
214 protocol_entry (SGEN_PROTOCOL_THREAD_REGISTER
, &entry
, sizeof (SGenProtocolThreadRegister
));
219 binary_protocol_thread_unregister (gpointer thread
)
221 SGenProtocolThreadUnregister entry
= { thread
};
222 protocol_entry (SGEN_PROTOCOL_THREAD_UNREGISTER
, &entry
, sizeof (SGenProtocolThreadUnregister
));
227 binary_protocol_missing_remset (gpointer obj
, gpointer obj_vtable
, int offset
, gpointer value
, gpointer value_vtable
, int value_pinned
)
229 SGenProtocolMissingRemset entry
= { obj
, obj_vtable
, offset
, value
, value_vtable
, value_pinned
};
230 protocol_entry (SGEN_PROTOCOL_MISSING_REMSET
, &entry
, sizeof (SGenProtocolMissingRemset
));