Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
uPython-mirror
Commits
8123a333
Commit
8123a333
authored
Apr 05, 2014
by
Damien George
Browse files
Merge pull request #425 from iabdalkader/del
Implement del
parents
ea13f407
cc849f70
Changes
6
Hide whitespace changes
Inline
Side-by-side
py/gc.c
View file @
8123a333
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "mpconfig.h"
#include "misc.h"
#include "gc.h"
#include "misc.h"
#include "qstr.h"
#include "obj.h"
#include "runtime.h"
#if MICROPY_ENABLE_GC
#if 0 // print debugging info
...
...
@@ -21,7 +27,9 @@ typedef unsigned char byte;
#define STACK_SIZE (64) // tunable; minimum is 1
STATIC
byte
*
gc_alloc_table_start
;
STATIC
byte
*
gc_mpobj_table_start
;
STATIC
machine_uint_t
gc_alloc_table_byte_len
;
STATIC
machine_uint_t
gc_mpobj_table_byte_len
;
STATIC
machine_uint_t
*
gc_pool_start
;
STATIC
machine_uint_t
*
gc_pool_end
;
...
...
@@ -59,6 +67,10 @@ STATIC machine_uint_t *gc_sp;
#define ATB_HEAD_TO_MARK(block) do { gc_alloc_table_start[(block) / BLOCKS_PER_ATB] |= (AT_MARK << BLOCK_SHIFT(block)); } while (0)
#define ATB_MARK_TO_HEAD(block) do { gc_alloc_table_start[(block) / BLOCKS_PER_ATB] &= (~(AT_TAIL << BLOCK_SHIFT(block))); } while (0)
#define ATB_SET_MPOBJ(block) do { gc_mpobj_table_start[(block) / 8] |= (1<<(block%8)); } while (0)
#define ATB_CLR_MPOBJ(block) do { gc_mpobj_table_start[(block) / 8] &= (~(1<<(block%8))); } while (0)
#define ATB_IS_MPOBJ(block) ((gc_mpobj_table_start[(block) / 8]>>(block%8))&0x01)
#define BLOCK_FROM_PTR(ptr) (((ptr) - (machine_uint_t)gc_pool_start) / BYTES_PER_BLOCK)
#define PTR_FROM_BLOCK(block) (((block) * BYTES_PER_BLOCK + (machine_uint_t)gc_pool_start))
#define ATB_FROM_BLOCK(bl) ((bl) / BLOCKS_PER_ATB)
...
...
@@ -73,7 +85,11 @@ void gc_init(void *start, void *end) {
machine_uint_t
total_word_len
=
(
machine_uint_t
*
)
end
-
(
machine_uint_t
*
)
start
;
gc_alloc_table_byte_len
=
total_word_len
*
BYTES_PER_WORD
/
(
1
+
BITS_PER_BYTE
/
2
*
BYTES_PER_BLOCK
);
gc_alloc_table_start
=
(
byte
*
)
start
;
machine_uint_t
gc_pool_block_len
=
gc_alloc_table_byte_len
*
BITS_PER_BYTE
/
2
;
gc_mpobj_table_byte_len
=
(
gc_alloc_table_byte_len
*
BITS_PER_BYTE
/
2
)
/
8
;
gc_mpobj_table_start
=
gc_alloc_table_start
+
gc_alloc_table_byte_len
;
machine_uint_t
gc_pool_block_len
=
(
gc_alloc_table_byte_len
*
BITS_PER_BYTE
/
2
)
-
(
gc_mpobj_table_byte_len
/
BYTES_PER_BLOCK
);
machine_uint_t
gc_pool_word_len
=
gc_pool_block_len
*
WORDS_PER_BLOCK
;
gc_pool_start
=
(
machine_uint_t
*
)
end
-
gc_pool_word_len
;
gc_pool_end
=
end
;
...
...
@@ -81,6 +97,9 @@ void gc_init(void *start, void *end) {
// clear ATBs
memset
(
gc_alloc_table_start
,
0
,
gc_alloc_table_byte_len
);
// clear MPOBJ flags
memset
(
gc_mpobj_table_start
,
0
,
gc_mpobj_table_byte_len
);
// allocate first block because gc_pool_start points there and it will never
// be freed, so allocating 1 block with null pointers will minimise memory loss
ATB_FREE_TO_HEAD
(
0
);
...
...
@@ -157,6 +176,16 @@ STATIC void gc_sweep(void) {
for
(
machine_uint_t
block
=
0
;
block
<
gc_alloc_table_byte_len
*
BLOCKS_PER_ATB
;
block
++
)
{
switch
(
ATB_GET_KIND
(
block
))
{
case
AT_HEAD
:
if
(
ATB_IS_MPOBJ
(
block
))
{
mp_obj_t
dest
[
2
];
mp_load_method
((
mp_obj_t
*
)
PTR_FROM_BLOCK
(
block
),
MP_QSTR___del__
,
dest
);
// load_method returned a method
if
(
dest
[
1
]
!=
MP_OBJ_NULL
)
{
mp_call_method_n_kw
(
0
,
0
,
dest
);
}
// clear mpobj flag
ATB_CLR_MPOBJ
(
block
);
}
free_tail
=
1
;
// fall through to free the head
...
...
@@ -237,7 +266,7 @@ void gc_info(gc_info_t *info) {
info
->
free
*=
BYTES_PER_BLOCK
;
}
void
*
gc_alloc
(
machine_uint_t
n_bytes
)
{
void
*
_
gc_alloc
(
machine_uint_t
n_bytes
,
bool
is_mpobj
)
{
machine_uint_t
n_blocks
=
((
n_bytes
+
BYTES_PER_BLOCK
-
1
)
&
(
~
(
BYTES_PER_BLOCK
-
1
)))
/
BYTES_PER_BLOCK
;
DEBUG_printf
(
"gc_alloc("
UINT_FMT
" bytes -> "
UINT_FMT
" blocks)
\n
"
,
n_bytes
,
n_blocks
);
...
...
@@ -286,10 +315,23 @@ found:
ATB_FREE_TO_TAIL
(
bl
);
}
if
(
is_mpobj
)
{
// set mp_obj flag only if it has del
ATB_SET_MPOBJ
(
start_block
);
}
// return pointer to first block
return
(
void
*
)(
gc_pool_start
+
start_block
*
WORDS_PER_BLOCK
);
}
void
*
gc_alloc
(
machine_uint_t
n_bytes
)
{
return
_gc_alloc
(
n_bytes
,
false
);
}
void
*
gc_alloc_mp_obj
(
machine_uint_t
n_bytes
)
{
return
_gc_alloc
(
n_bytes
,
true
);
}
// force the freeing of a piece of memory
void
gc_free
(
void
*
ptr_in
)
{
machine_uint_t
ptr
=
(
machine_uint_t
)
ptr_in
;
...
...
py/gc.h
View file @
8123a333
...
...
@@ -4,6 +4,7 @@ void gc_collect_root(void **ptrs, machine_uint_t len);
void
gc_collect_end
(
void
);
void
gc_collect
(
void
);
void
*
gc_alloc
(
machine_uint_t
n_bytes
);
void
*
gc_alloc_mp_obj
(
machine_uint_t
n_bytes
);
void
gc_free
(
void
*
ptr
);
machine_uint_t
gc_nbytes
(
void
*
ptr
);
void
*
gc_realloc
(
void
*
ptr
,
machine_uint_t
n_bytes
);
...
...
py/malloc.c
View file @
8123a333
...
...
@@ -31,6 +31,7 @@ STATIC int peak_bytes_allocated = 0;
#undef free
#undef realloc
#define malloc gc_alloc
#define malloc_mp_obj gc_alloc_mp_obj
#define free gc_free
#define realloc gc_realloc
#endif // MICROPY_ENABLE_GC
...
...
@@ -52,6 +53,24 @@ void *m_malloc(int num_bytes) {
return
ptr
;
}
void
*
m_malloc_mp_obj
(
int
num_bytes
)
{
if
(
num_bytes
==
0
)
{
return
NULL
;
}
void
*
ptr
=
malloc_mp_obj
(
num_bytes
);
if
(
ptr
==
NULL
)
{
printf
(
"could not allocate memory, allocating %d bytes
\n
"
,
num_bytes
);
return
NULL
;
}
#if MICROPY_MEM_STATS
total_bytes_allocated
+=
num_bytes
;
current_bytes_allocated
+=
num_bytes
;
UPDATE_PEAK
();
#endif
DEBUG_printf
(
"malloc %d : %p
\n
"
,
num_bytes
,
ptr
);
return
ptr
;
}
void
*
m_malloc0
(
int
num_bytes
)
{
void
*
ptr
=
m_malloc
(
num_bytes
);
if
(
ptr
!=
NULL
)
{
...
...
py/misc.h
View file @
8123a333
...
...
@@ -27,12 +27,14 @@ typedef unsigned int uint;
#define m_new0(type, num) ((type*)(m_malloc0(sizeof(type) * (num))))
#define m_new_obj(type) (m_new(type, 1))
#define m_new_obj_var(obj_type, var_type, var_num) ((obj_type*)m_malloc(sizeof(obj_type) + sizeof(var_type) * (var_num)))
#define m_new_mp_obj(type)((type*)(m_malloc_mp_obj(sizeof(type))))
#define m_renew(type, ptr, old_num, new_num) ((type*)(m_realloc((ptr), sizeof(type) * (old_num), sizeof(type) * (new_num))))
#define m_del(type, ptr, num) m_free(ptr, sizeof(type) * (num))
#define m_del_obj(type, ptr) (m_del(type, ptr, 1))
#define m_del_var(obj_type, var_type, var_num, ptr) (m_free(ptr, sizeof(obj_type) + sizeof(var_type) * (var_num)))
void
*
m_malloc
(
int
num_bytes
);
void
*
m_malloc_mp_obj
(
int
num_bytes
);
void
*
m_malloc0
(
int
num_bytes
);
void
*
m_realloc
(
void
*
ptr
,
int
old_num_bytes
,
int
new_num_bytes
);
void
m_free
(
void
*
ptr
,
int
num_bytes
);
...
...
py/qstrdefs.h
View file @
8123a333
...
...
@@ -27,6 +27,7 @@ Q(__sub__)
Q
(
__repr__
)
Q
(
__str__
)
Q
(
__getattr__
)
Q
(
__del__
)
Q
(
micropython
)
Q
(
byte_code
)
...
...
stm/file.c
View file @
8123a333
...
...
@@ -56,6 +56,7 @@ STATIC const mp_map_elem_t file_locals_dict_table[] = {
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_read
),
(
mp_obj_t
)
&
file_obj_read_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_write
),
(
mp_obj_t
)
&
file_obj_write_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_close
),
(
mp_obj_t
)
&
file_obj_close_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR___del__
),
(
mp_obj_t
)
&
file_obj_close_obj
},
};
STATIC
MP_DEFINE_CONST_DICT
(
file_locals_dict
,
file_locals_dict_table
);
...
...
@@ -70,7 +71,7 @@ static const mp_obj_type_t file_obj_type = {
mp_obj_t
pyb_io_open
(
mp_obj_t
o_filename
,
mp_obj_t
o_mode
)
{
const
char
*
filename
=
mp_obj_str_get_str
(
o_filename
);
const
char
*
mode
=
mp_obj_str_get_str
(
o_mode
);
pyb_file_obj_t
*
self
=
m_new_obj
(
pyb_file_obj_t
);
pyb_file_obj_t
*
self
=
m_new_
mp_
obj
(
pyb_file_obj_t
);
self
->
base
.
type
=
&
file_obj_type
;
if
(
mode
[
0
]
==
'r'
)
{
// open for reading
...
...
Write
Preview
Supports
Markdown
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