Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
Pyston
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
Pyston
Commits
f665e516
Commit
f665e516
authored
Mar 24, 2016
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Copy CPython's float freelist
(we had already copied their int freelist)
parent
90fe1528
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
117 additions
and
21 deletions
+117
-21
src/runtime/float.cpp
src/runtime/float.cpp
+80
-4
src/runtime/int.cpp
src/runtime/int.cpp
+7
-14
src/runtime/types.cpp
src/runtime/types.cpp
+2
-1
src/runtime/types.h
src/runtime/types.h
+28
-2
No files found.
src/runtime/float.cpp
View file @
f665e516
...
...
@@ -41,6 +41,86 @@ extern "C" int float_pow_unboxed(double iv, double iw, double* res) noexcept;
namespace
pyston
{
/* Special free list -- see comments for same code in intobject.c. */
#define BLOCK_SIZE 1000
/* 1K less typical malloc overhead */
#define BHEAD_SIZE 8
/* Enough for a 64-bit pointer */
#define N_FLOATOBJECTS ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyFloatObject))
struct
_floatblock
{
struct
_floatblock
*
next
;
PyFloatObject
objects
[
N_FLOATOBJECTS
];
};
typedef
struct
_floatblock
PyFloatBlock
;
static
PyFloatBlock
*
block_list
=
NULL
;
PyFloatObject
*
BoxedFloat
::
free_list
=
NULL
;
PyFloatObject
*
BoxedFloat
::
fill_free_list
(
void
)
noexcept
{
PyFloatObject
*
p
,
*
q
;
/* XXX Float blocks escape the object heap. Use PyObject_MALLOC ??? */
p
=
(
PyFloatObject
*
)
PyMem_MALLOC
(
sizeof
(
PyFloatBlock
));
if
(
p
==
NULL
)
return
(
PyFloatObject
*
)
PyErr_NoMemory
();
((
PyFloatBlock
*
)
p
)
->
next
=
block_list
;
block_list
=
(
PyFloatBlock
*
)
p
;
p
=
&
((
PyFloatBlock
*
)
p
)
->
objects
[
0
];
q
=
p
+
N_FLOATOBJECTS
;
while
(
--
q
>
p
)
q
->
ob_type
=
(
struct
_typeobject
*
)(
q
-
1
);
q
->
ob_type
=
NULL
;
return
p
+
N_FLOATOBJECTS
-
1
;
}
void
BoxedFloat
::
tp_dealloc
(
Box
*
b
)
noexcept
{
#ifdef DISABLE_INT_FREELIST
b
->
cls
->
tp_free
(
b
);
#else
if
(
PyFloat_CheckExact
(
b
))
{
PyFloatObject
*
v
=
(
PyFloatObject
*
)(
b
);
v
->
ob_type
=
(
struct
_typeobject
*
)
free_list
;
free_list
=
v
;
}
else
{
b
->
cls
->
tp_free
(
b
);
}
#endif
}
extern
"C"
int
PyFloat_ClearFreeList
()
noexcept
{
PyFloatObject
*
p
;
PyFloatBlock
*
list
,
*
next
;
int
i
;
int
u
;
/* remaining unfreed ints per block */
int
freelist_size
=
0
;
list
=
block_list
;
block_list
=
NULL
;
BoxedFloat
::
free_list
=
NULL
;
while
(
list
!=
NULL
)
{
u
=
0
;
for
(
i
=
0
,
p
=
&
list
->
objects
[
0
];
i
<
N_FLOATOBJECTS
;
i
++
,
p
++
)
{
if
(
PyFloat_CheckExact
((
BoxedFloat
*
)
p
)
&&
Py_REFCNT
(
p
)
!=
0
)
u
++
;
}
next
=
list
->
next
;
if
(
u
)
{
list
->
next
=
block_list
;
block_list
=
list
;
for
(
i
=
0
,
p
=
&
list
->
objects
[
0
];
i
<
N_FLOATOBJECTS
;
i
++
,
p
++
)
{
if
(
!
PyFloat_CheckExact
((
BoxedFloat
*
)
p
)
||
Py_REFCNT
(
p
)
==
0
)
{
p
->
ob_type
=
(
struct
_typeobject
*
)
BoxedFloat
::
free_list
;
BoxedFloat
::
free_list
=
p
;
}
}
}
else
{
PyMem_FREE
(
list
);
}
freelist_size
+=
u
;
list
=
next
;
}
return
freelist_size
;
}
extern
"C"
PyObject
*
PyFloat_FromDouble
(
double
d
)
noexcept
{
return
boxFloat
(
d
);
}
...
...
@@ -1631,10 +1711,6 @@ static PyMethodDef float_methods[]
{
"is_integer"
,
(
PyCFunction
)
float_is_integer
,
METH_NOARGS
,
NULL
},
{
"__format__"
,
(
PyCFunction
)
float__format__
,
METH_VARARGS
,
NULL
}
};
extern
"C"
int
PyFloat_ClearFreeList
()
noexcept
{
return
0
;
// number of entries cleared
}
void
setupFloat
()
{
static
PyNumberMethods
float_as_number
;
float_cls
->
tp_as_number
=
&
float_as_number
;
...
...
src/runtime/int.cpp
View file @
f665e516
...
...
@@ -87,27 +87,20 @@ PyIntObject* BoxedInt::fill_free_list(void) noexcept {
return
p
+
N_INTOBJECTS
-
1
;
}
void
BoxedInt
::
tp_dealloc
(
Box
*
v
)
noexcept
{
void
BoxedInt
::
tp_dealloc
(
Box
*
b
)
noexcept
{
#ifdef DISABLE_INT_FREELIST
v
->
cls
->
tp_free
(
v
);
b
->
cls
->
tp_free
(
b
);
#else
if
(
PyInt_CheckExact
(
v
))
{
BoxedInt
::
tp_free
(
v
);
if
(
PyInt_CheckExact
(
b
))
{
PyIntObject
*
v
=
(
PyIntObject
*
)(
b
);
v
->
ob_type
=
(
struct
_typeobject
*
)
free_list
;
free_list
=
v
;
}
else
{
v
->
cls
->
tp_free
(
v
);
b
->
cls
->
tp_free
(
b
);
}
#endif
}
void
BoxedInt
::
tp_free
(
void
*
b
)
noexcept
{
#ifdef DISABLE_INT_FREELIST
assert
(
0
);
#endif
PyIntObject
*
v
=
static_cast
<
PyIntObject
*>
(
b
);
v
->
ob_type
=
(
struct
_typeobject
*
)
free_list
;
free_list
=
v
;
}
extern
"C"
unsigned
long
PyInt_AsUnsignedLongMask
(
PyObject
*
op
)
noexcept
{
if
(
op
&&
PyInt_Check
(
op
))
return
PyInt_AS_LONG
((
PyIntObject
*
)
op
);
...
...
src/runtime/types.cpp
View file @
f665e516
...
...
@@ -4217,7 +4217,8 @@ void setupRuntime() {
complex_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedComplex
),
false
,
"complex"
,
true
,
NULL
,
NULL
,
false
);
long_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedLong
),
false
,
"long"
,
true
,
NULL
,
NULL
,
false
);
long_cls
->
tp_flags
|=
Py_TPFLAGS_LONG_SUBCLASS
;
float_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedFloat
),
false
,
"float"
,
true
,
NULL
,
NULL
,
false
);
float_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedFloat
),
false
,
"float"
,
true
,
BoxedFloat
::
tp_dealloc
,
NULL
,
false
);
function_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
offsetof
(
BoxedFunction
,
attrs
),
offsetof
(
BoxedFunction
,
weakreflist
),
sizeof
(
BoxedFunction
),
false
,
"function"
,
false
,
functionDtor
,
NULL
,
true
,
(
traverseproc
)
func_traverse
,
NOCLEAR
);
...
...
src/runtime/types.h
View file @
f665e516
...
...
@@ -475,20 +475,46 @@ public:
}
static
void
tp_dealloc
(
Box
*
b
)
noexcept
;
static
void
tp_free
(
void
*
b
)
noexcept
;
friend
int
PyInt_ClearFreeList
()
noexcept
;
};
static_assert
(
sizeof
(
BoxedInt
)
==
sizeof
(
PyIntObject
),
""
);
static_assert
(
offsetof
(
BoxedInt
,
n
)
==
offsetof
(
PyIntObject
,
ob_ival
),
""
);
extern
"C"
int
PyFloat_ClearFreeList
()
noexcept
;
class
BoxedFloat
:
public
Box
{
private:
static
PyFloatObject
*
free_list
;
static
PyFloatObject
*
fill_free_list
()
noexcept
;
public:
double
d
;
BoxedFloat
(
double
d
)
__attribute__
((
visibility
(
"default"
)))
:
d
(
d
)
{}
DEFAULT_CLASS_SIMPLE
(
float_cls
,
false
);
void
*
operator
new
(
size_t
size
,
BoxedClass
*
cls
)
__attribute__
((
visibility
(
"default"
)))
{
return
Box
::
operator
new
(
size
,
cls
);
}
// float uses a customized allocator, so we can't use DEFAULT_CLASS_SIMPLE (which inlines the default allocator)
void
*
operator
new
(
size_t
size
)
__attribute__
((
visibility
(
"default"
)))
{
#ifdef DISABLE_INT_FREELIST
return
Box
::
operator
new
(
size
,
float_cls
);
#else
if
(
unlikely
(
free_list
==
NULL
))
{
free_list
=
fill_free_list
();
assert
(
free_list
);
}
PyFloatObject
*
v
=
free_list
;
free_list
=
(
PyFloatObject
*
)
v
->
ob_type
;
PyObject_INIT
((
BoxedFloat
*
)
v
,
&
PyFloat_Type
);
return
v
;
#endif
}
static
void
tp_dealloc
(
Box
*
b
)
noexcept
;
friend
int
PyFloat_ClearFreeList
()
noexcept
;
};
static_assert
(
sizeof
(
BoxedFloat
)
==
sizeof
(
PyFloatObject
),
""
);
static_assert
(
offsetof
(
BoxedFloat
,
d
)
==
offsetof
(
PyFloatObject
,
ob_fval
),
""
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment