Skip to content

Commit 545fe91

Browse files
authored
Merge pull request #1 from nedbat/nedbat/fix-32
Fix some build issues on CI servers.
2 parents 649fb2a + c72c58d commit 545fe91

File tree

5 files changed

+61
-31
lines changed

5 files changed

+61
-31
lines changed

coverage/ctracer/module.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,24 +44,24 @@ PyInit_tracer(void)
4444
return NULL;
4545
}
4646

47-
InternTableType.tp_new = PyType_GenericNew;
48-
if (PyType_Ready(&InternTableType) < 0) {
47+
Py_INCREF(&CTracerType);
48+
if (PyModule_AddObject(mod, "CTracer", (PyObject *)&CTracerType) < 0) {
4949
Py_DECREF(mod);
50+
Py_DECREF(&CTracerType);
5051
return NULL;
5152
}
5253

53-
Py_INCREF(&CTracerType);
54-
if (PyModule_AddObject(mod, "CTracer", (PyObject *)&CTracerType) < 0) {
54+
/* Initialize InternTable */
55+
InternTableType.tp_new = PyType_GenericNew;
56+
if (PyType_Ready(&InternTableType) < 0) {
5557
Py_DECREF(mod);
56-
Py_DECREF(&CTracerType);
5758
return NULL;
5859
}
5960

6061
Py_INCREF(&InternTableType);
6162
if (PyModule_AddObject(mod, "InternTable", (PyObject *)&InternTableType) < 0) {
6263
Py_DECREF(mod);
6364
Py_DECREF(&InternTableType);
64-
Py_DECREF(&InternTableType);
6565
return NULL;
6666
}
6767

@@ -70,13 +70,15 @@ PyInit_tracer(void)
7070
if (PyType_Ready(&CFileDispositionType) < 0) {
7171
Py_DECREF(mod);
7272
Py_DECREF(&CTracerType);
73+
Py_DECREF(&InternTableType);
7374
return NULL;
7475
}
7576

7677
Py_INCREF(&CFileDispositionType);
7778
if (PyModule_AddObject(mod, "CFileDisposition", (PyObject *)&CFileDispositionType) < 0) {
7879
Py_DECREF(mod);
7980
Py_DECREF(&CTracerType);
81+
Py_DECREF(&InternTableType);
8082
Py_DECREF(&CFileDispositionType);
8183
return NULL;
8284
}
@@ -109,6 +111,15 @@ inittracer(void)
109111
Py_INCREF(&CTracerType);
110112
PyModule_AddObject(mod, "CTracer", (PyObject *)&CTracerType);
111113

114+
/* Initialize InternTable */
115+
InternTableType.tp_new = PyType_GenericNew;
116+
if (PyType_Ready(&InternTableType) < 0) {
117+
return;
118+
}
119+
120+
Py_INCREF(&InternTableType);
121+
PyModule_AddObject(mod, "InternTable", (PyObject *)&InternTableType);
122+
112123
/* Initialize CFileDisposition */
113124
CFileDispositionType.tp_new = PyType_GenericNew;
114125
if (PyType_Ready(&CFileDispositionType) < 0) {

coverage/ctracer/tracer.c

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ static void InternTable_init_1(InternTable *table){
7272
}
7373

7474
static void InternTable_dealloc_1(InternTable *table){
75-
Py_XDECREF(table->zero_value);
7675
size_t j;
76+
Py_XDECREF(table->zero_value);
7777
for(j = 0; j < table->capacity; j++){
7878
Py_XDECREF(table->entries[j].value);
7979
}
@@ -194,7 +194,7 @@ static const char * what_sym[] = {"CALL", "EXC ", "LINE", "RET "};
194194

195195
// From http://www.cris.com/~Ttwang/tech/inthash.htm via
196196
// https://chromium.googlesource.com/chromium/blink/+/master/Source/wtf/HashFunctions.h
197-
static uint64_t hash64(uint64_t key){
197+
static PY_LONG_LONG hash64(PY_LONG_LONG key){
198198
key += ~(key << 32);
199199
key ^= (key >> 22);
200200
key += ~(key << 13);
@@ -211,7 +211,7 @@ static uint64_t hash64(uint64_t key){
211211
InternTable_lookup
212212
*/
213213
static PyObject **
214-
InternTable_lookup(InternTable *table, uint64_t key);
214+
InternTable_lookup(InternTable *table, PY_LONG_LONG key);
215215

216216
/*
217217
Core implementation of the InternTable hash table.
@@ -223,8 +223,8 @@ InternTable_lookup(InternTable *table, uint64_t key);
223223
returns a value pointer for the key.
224224
225225
*/
226-
static inline PyObject ** InternEntry_matches(
227-
InternTable *table, size_t location, uint64_t key
226+
static PyObject ** InternEntry_matches(
227+
InternTable *table, size_t location, PY_LONG_LONG key
228228
){
229229
size_t index = location & (table->capacity - 1);
230230
InternEntry *entry = table->entries + index;
@@ -263,7 +263,7 @@ static inline PyObject ** InternEntry_matches(
263263
}
264264
}
265265
free(old_entries);
266-
assert(table->current_fill == old_fill);
266+
assert(table->current_fill == old_fill); (void)(old_fill);
267267

268268
/* The shape of the table has changed and the caller doesn't know
269269
about that, so we just recurse and look up the key in the new
@@ -288,17 +288,19 @@ a freshly created key it will be a pointer to null. The caller should then
288288
populate the cell with the newly created object.
289289
*/
290290
static PyObject **
291-
InternTable_lookup(InternTable *table, uint64_t key){
291+
InternTable_lookup(InternTable *table, PY_LONG_LONG key){
292292
size_t i;
293+
PyObject ** initial_attempt;
294+
size_t probe;
293295

294296
if(key == 0){
295297
return &(table->zero_value);
296298
}
297-
PyObject ** initial_attempt = InternEntry_matches(table, key, key);
299+
initial_attempt = InternEntry_matches(table, key, key);
298300
if(initial_attempt != NULL){
299301
return initial_attempt;
300302
}
301-
size_t probe = hash64(key) & (table->capacity - 1);
303+
probe = hash64(key) & (table->capacity - 1);
302304
for(i = 0; i < table->capacity; i++){
303305
PyObject ** attempt = InternEntry_matches(table, probe + i, key);
304306
if(attempt != NULL){
@@ -316,17 +318,17 @@ CTracer_record_pair(CTracer *self, int l1, int l2)
316318
int ret = RET_ERROR;
317319

318320
/*
319-
We combine the two int values into a uint64_t in a slightly odd way: Rather
321+
We combine the two int values into a PY_LONG_LONG in a slightly odd way: Rather
320322
than just concatenate them, we xor them together for the low bits. The
321323
reason for this is that it allows us to trigger our no-hash lookup in the
322324
table more often, because it ensures a reasonable range of diversity in the
323325
low bits. We can recreate the original key as u1 = key >> 32,
324326
u2 = ((uint32_t)u1) ^ ((uint32_t)key), so this still maps the tuple to a
325327
unique key.
326328
*/
327-
uint64_t u1 = (uint32_t)l1;
328-
uint64_t u2 = (uint32_t)l2;
329-
uint64_t key = (u1 << 32) | (u1 ^ u2);
329+
PY_LONG_LONG u1 = (PY_UINT32_T)l1;
330+
PY_LONG_LONG u2 = (PY_UINT32_T)l2;
331+
PY_LONG_LONG key = (u1 << 32) | (u1 ^ u2);
330332

331333
PyObject ** container = InternTable_lookup(
332334
&self->intern_table, key);
@@ -355,7 +357,7 @@ static int
355357
CTracer_record_int(CTracer *self, int lineno_from){
356358

357359
PyObject ** container = InternTable_lookup(
358-
&self->intern_table, (uint64_t)lineno_from);
360+
&self->intern_table, (PY_LONG_LONG)lineno_from);
359361

360362
PyObject * this_line = *container;
361363
if (this_line == NULL) {
@@ -1367,14 +1369,17 @@ InternTable_dealloc(InternTableObject *self)
13671369

13681370
static PyObject *InternTable_getitem(InternTableObject *self, PyObject *key)
13691371
{
1372+
PY_LONG_LONG int_key;
1373+
PyObject **result;
1374+
13701375
assert(self->table.entries);
13711376
PyErr_Clear();
1372-
uint64_t int_key = PyLong_AsUnsignedLongLong(key);
1377+
int_key = MyInt_AsLongLong(key);
13731378
if(PyErr_Occurred()){
13741379
return NULL;
13751380
}
13761381

1377-
PyObject **result = InternTable_lookup(&self->table, int_key);
1382+
result = InternTable_lookup(&self->table, int_key);
13781383
if(*result == NULL){
13791384
return Py_None;
13801385
}
@@ -1385,13 +1390,16 @@ static PyObject *InternTable_getitem(InternTableObject *self, PyObject *key)
13851390

13861391
static int InternTable_setitem(InternTableObject *self, PyObject *key, PyObject *value)
13871392
{
1393+
PY_LONG_LONG int_key;
1394+
PyObject **result;
1395+
13881396
assert(self->table.entries);
13891397

13901398
PyErr_Clear();
1391-
uint64_t int_key = PyLong_AsUnsignedLongLong(key);
1399+
int_key = MyInt_AsLongLong(key);
13921400
if(PyErr_Occurred()) return RET_ERROR;
13931401

1394-
PyObject **result = InternTable_lookup(&self->table, int_key);
1402+
result = InternTable_lookup(&self->table, int_key);
13951403
if(*result != NULL){
13961404
Py_XDECREF(*result);
13971405
}

coverage/ctracer/tracer.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#include "structmember.h"
99
#include "frameobject.h"
1010
#include "opcode.h"
11-
#include <stdint.h>
1211

1312
#include "datastack.h"
1413

@@ -25,13 +24,13 @@ that in the common case where the tracer has already seen the key somewhere we
2524
don't need to allocate a new one. This can significantly speed up tracing.
2625
*/
2726
typedef struct InternEntry {
28-
uint64_t key;
27+
PY_LONG_LONG key;
2928
PyObject *value;
3029
} InternEntry;
3130

3231
typedef struct InternTable {
3332
/* Store the value keyed off zero separately. This allows us to use a key
34-
of zero as a not-set indicator. */
33+
of zero as a not-set indicator. */
3534
PyObject * zero_value;
3635

3736
/* The number of elements in our entries array (including absent elements).
@@ -46,7 +45,7 @@ typedef struct InternTable {
4645
the same fraction of capacity. */
4746
size_t max_fill;
4847

49-
/* Essentially (key, value) tuples where keys are uint64_t and values are
48+
/* Essentially (key, value) tuples where keys are PY_LONG_LONG and values are
5049
*PyObject. Values are owned by the tracer and will have their refcount
5150
decremented appropriately on release.*/
5251
InternEntry * entries;
@@ -58,7 +57,7 @@ typedef struct InternTable {
5857
else.
5958
*/
6059
typedef struct InternTableObject{
61-
PyObject_HEAD;
60+
PyObject_HEAD
6261
InternTable table;
6362
} InternTableObject;
6463

coverage/ctracer/util.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#define MyText_FromFormat PyUnicode_FromFormat
2525
#define MyInt_FromInt(i) PyLong_FromLong((long)i)
2626
#define MyInt_AsInt(o) (int)PyLong_AsLong(o)
27+
#define MyInt_AsLongLong(o) PyLong_AsUnsignedLongLong(o)
2728
#define MyText_InternFromString(s) PyUnicode_InternFromString(s)
2829

2930
#define MyType_HEAD_INIT PyVarObject_HEAD_INIT(NULL, 0)
@@ -37,6 +38,7 @@
3738
#define MyText_AsString(o) PyString_AsString(o)
3839
#define MyText_FromFormat PyUnicode_FromFormat
3940
#define MyInt_FromInt(i) PyInt_FromLong((long)i)
41+
#define MyInt_AsLongLong(o) PyInt_AsUnsignedLongLongMask(o)
4042
#define MyInt_AsInt(o) (int)PyInt_AsLong(o)
4143
#define MyText_InternFromString(s) PyString_InternFromString(s)
4244

tests/test_intern_table.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
1+
import sys
2+
13
from tests.coveragetest import CoverageTest
24

35
from hypothesis import given, example
46
import hypothesis.strategies as st
5-
from coverage.tracer import InternTable
6-
import sys
7+
import pytest
8+
9+
from coverage import env
710

11+
if env.C_TRACER:
12+
from coverage.tracer import InternTable
813

14+
15+
@pytest.mark.skipif(not env.C_TRACER, reason="Only the C tracer has refcounting issues")
916
class TestInternTable(CoverageTest):
17+
18+
run_in_temp_dir = False
19+
1020
@example([0])
1121
@given(st.lists(st.integers(0, 2 ** 64 - 1), unique=True))
1222
def test_interns_as_none_by_default(self, ls):

0 commit comments

Comments
 (0)