Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mruby
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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
mruby
Commits
6de0fcbd
Unverified
Commit
6de0fcbd
authored
Dec 27, 2021
by
Yukihiro "Matz" Matsumoto
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
class.c: remove `mt_elem` structure to avoid alignment gaps.
parent
a388d609
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
91 additions
and
88 deletions
+91
-88
src/class.c
src/class.c
+91
-88
No files found.
src/class.c
View file @
6de0fcbd
...
@@ -23,18 +23,22 @@ union mt_ptr {
...
@@ -23,18 +23,22 @@ union mt_ptr {
mrb_func_t
func
;
mrb_func_t
func
;
};
};
struct
mt_elem
{
#define MT_KEY_P(k) (((k)>>2) != 0)
union
mt_ptr
ptr
;
#define MT_FUNC_P 1
size_t
func_p
:
1
;
#define MT_NOARG_P 2
size_t
noarg_p
:
1
;
#define MT_EMPTY 0
mrb_sym
key
:
sizeof
(
mrb_sym
)
*
8
-
2
;
#define MT_DELETED 1
};
#define MT_KEY(sym, flags) ((sym)<<2|(flags))
#define MT_FLAGS(func_p, noarg_p) ((func_p)?MT_FUNC_P:0)|((noarg_p)?MT_NOARG_P:0)
#define MT_KEY_SYM(k) ((k)>>2)
#define MT_KEY_FLG(k) ((k)&3)
/* method table structure */
/* method table structure */
typedef
struct
mt_tbl
{
typedef
struct
mt_tbl
{
size_t
size
;
size_t
size
;
size_t
alloc
;
size_t
alloc
;
struct
mt_elem
*
table
;
union
mt_ptr
*
ptr
;
}
mt_tbl
;
}
mt_tbl
;
#ifdef MRB_USE_INLINE_METHOD_CACHE
#ifdef MRB_USE_INLINE_METHOD_CACHE
...
@@ -51,101 +55,99 @@ mt_new(mrb_state *mrb)
...
@@ -51,101 +55,99 @@ mt_new(mrb_state *mrb)
t
=
(
mt_tbl
*
)
mrb_malloc
(
mrb
,
sizeof
(
mt_tbl
));
t
=
(
mt_tbl
*
)
mrb_malloc
(
mrb
,
sizeof
(
mt_tbl
));
t
->
size
=
0
;
t
->
size
=
0
;
t
->
alloc
=
0
;
t
->
alloc
=
0
;
t
->
table
=
NULL
;
t
->
ptr
=
NULL
;
return
t
;
return
t
;
}
}
static
struct
mt_elem
*
mt_put
(
mrb_state
*
mrb
,
mt_tbl
*
t
,
mrb_sym
sym
,
size_t
func_p
,
size_t
noarg_p
,
union
mt_ptr
ptr
);
static
void
mt_put
(
mrb_state
*
mrb
,
mt_tbl
*
t
,
mrb_sym
sym
,
mrb_sym
flags
,
union
mt_ptr
ptr
);
static
void
static
void
mt_rehash
(
mrb_state
*
mrb
,
mt_tbl
*
t
)
mt_rehash
(
mrb_state
*
mrb
,
mt_tbl
*
t
)
{
{
size_t
old_alloc
=
t
->
alloc
;
size_t
old_alloc
=
t
->
alloc
;
size_t
new_alloc
=
old_alloc
+
8
;
size_t
new_alloc
=
old_alloc
+
8
;
struct
mt_elem
*
old_table
=
t
->
table
;
union
mt_ptr
*
old_ptr
=
t
->
ptr
;
khash_power2
(
new_alloc
);
khash_power2
(
new_alloc
);
if
(
old_alloc
==
new_alloc
)
return
;
if
(
old_alloc
==
new_alloc
)
return
;
t
->
alloc
=
new_alloc
;
t
->
alloc
=
new_alloc
;
t
->
size
=
0
;
t
->
size
=
0
;
t
->
table
=
(
struct
mt_elem
*
)
mrb_calloc
(
mrb
,
sizeof
(
struct
mt_elem
),
new_alloc
);
t
->
ptr
=
(
union
mt_ptr
*
)
mrb_calloc
(
mrb
,
sizeof
(
union
mt_ptr
)
+
sizeof
(
mrb_sym
),
new_alloc
);
if
(
old_alloc
==
0
)
return
;
mrb_sym
*
keys
=
(
mrb_sym
*
)
&
old_ptr
[
old_alloc
];
union
mt_ptr
*
vals
=
old_ptr
;
for
(
size_t
i
=
0
;
i
<
old_alloc
;
i
++
)
{
for
(
size_t
i
=
0
;
i
<
old_alloc
;
i
++
)
{
struct
mt_elem
*
slot
=
&
old_table
[
i
];
mrb_sym
key
=
keys
[
i
];
if
(
MT_KEY_P
(
key
))
{
/* key = 0 means empty or deleted */
mt_put
(
mrb
,
t
,
MT_KEY_SYM
(
key
),
MT_KEY_FLG
(
key
),
vals
[
i
]);
if
(
slot
->
key
!=
0
)
{
mt_put
(
mrb
,
t
,
slot
->
key
,
slot
->
func_p
,
slot
->
noarg_p
,
slot
->
ptr
);
}
}
}
}
mrb_free
(
mrb
,
old_
table
);
mrb_free
(
mrb
,
old_
ptr
);
}
}
#define slot_empty_p(slot) ((slot)->key == 0 && (slot)->func_p == 0)
#define slot_empty_p(slot) ((slot)->key == 0 && (slot)->func_p == 0)
/* Set the value for the symbol in the method table. */
/* Set the value for the symbol in the method table. */
static
struct
mt_elem
*
static
void
mt_put
(
mrb_state
*
mrb
,
mt_tbl
*
t
,
mrb_sym
sym
,
size_t
func_p
,
size_t
noarg_p
,
union
mt_ptr
ptr
)
mt_put
(
mrb_state
*
mrb
,
mt_tbl
*
t
,
mrb_sym
sym
,
mrb_sym
flags
,
union
mt_ptr
ptr
)
{
{
size_t
hash
,
pos
,
start
;
size_t
hash
,
pos
,
start
;
s
truct
mt_elem
*
dslot
=
NULL
;
s
size_t
dpos
=
-
1
;
if
(
t
->
alloc
==
0
)
{
if
(
t
->
alloc
==
0
)
{
mt_rehash
(
mrb
,
t
);
mt_rehash
(
mrb
,
t
);
}
}
mrb_sym
*
keys
=
(
mrb_sym
*
)
&
t
->
ptr
[
t
->
alloc
];
union
mt_ptr
*
vals
=
t
->
ptr
;
hash
=
kh_int_hash_func
(
mrb
,
sym
);
hash
=
kh_int_hash_func
(
mrb
,
sym
);
start
=
pos
=
hash
&
(
t
->
alloc
-
1
);
start
=
pos
=
hash
&
(
t
->
alloc
-
1
);
for
(;;)
{
for
(;;)
{
struct
mt_elem
*
slot
=
&
t
->
table
[
pos
];
mrb_sym
key
=
keys
[
pos
];
if
(
MT_KEY_SYM
(
key
)
==
sym
)
{
if
(
slot
->
key
==
sym
)
{
value_set:
slot
->
func_p
=
func_p
;
keys
[
pos
]
=
MT_KEY
(
sym
,
flags
);
slot
->
noarg_p
=
noarg_p
;
vals
[
pos
]
=
ptr
;
slot
->
ptr
=
ptr
;
return
;
return
slot
;
}
}
else
if
(
slot
->
key
==
0
)
{
/* empty or deleted */
else
if
(
key
==
MT_EMPTY
)
{
if
(
slot
->
func_p
==
0
)
{
/* empty */
t
->
size
++
;
t
->
size
++
;
goto
value_set
;
slot
->
key
=
sym
;
}
slot
->
func_p
=
func_p
;
else
if
(
key
==
MT_DELETED
&&
dpos
<
0
)
{
slot
->
noarg_p
=
noarg_p
;
dpos
=
pos
;
slot
->
ptr
=
ptr
;
return
slot
;
}
else
if
(
!
dslot
)
{
/* deleted */
dslot
=
slot
;
}
}
}
pos
=
(
pos
+
1
)
&
(
t
->
alloc
-
1
);
pos
=
(
pos
+
1
)
&
(
t
->
alloc
-
1
);
if
(
pos
==
start
)
{
/* not found */
if
(
pos
==
start
)
{
/* not found */
if
(
d
slot
)
{
if
(
d
pos
>
0
)
{
t
->
size
++
;
t
->
size
++
;
dslot
->
key
=
sym
;
pos
=
dpos
;
dslot
->
func_p
=
func_p
;
goto
value_set
;
dslot
->
noarg_p
=
noarg_p
;
dslot
->
ptr
=
ptr
;
return
dslot
;
}
}
/* no room */
/* no room */
mt_rehash
(
mrb
,
t
);
mt_rehash
(
mrb
,
t
);
start
=
pos
=
hash
&
(
t
->
alloc
-
1
);
start
=
pos
=
hash
&
(
t
->
alloc
-
1
);
keys
=
(
mrb_sym
*
)
&
t
->
ptr
[
t
->
alloc
];
vals
=
t
->
ptr
;
}
}
}
}
}
}
/* Get a value for a symbol from the method table. */
/* Get a value for a symbol from the method table. */
static
struct
mt_elem
*
static
mrb_sym
mt_get
(
mrb_state
*
mrb
,
mt_tbl
*
t
,
mrb_sym
sym
)
mt_get
(
mrb_state
*
mrb
,
mt_tbl
*
t
,
mrb_sym
sym
,
union
mt_ptr
*
pp
)
{
{
size_t
hash
,
pos
,
start
;
size_t
hash
,
pos
,
start
;
if
(
t
==
NULL
)
return
NULL
;
if
(
t
==
NULL
)
return
0
;
if
(
t
->
alloc
==
0
)
return
NULL
;
if
(
t
->
alloc
==
0
)
return
0
;
if
(
t
->
size
==
0
)
return
NULL
;
if
(
t
->
size
==
0
)
return
0
;
mrb_sym
*
keys
=
(
mrb_sym
*
)
&
t
->
ptr
[
t
->
alloc
];
union
mt_ptr
*
vals
=
t
->
ptr
;
hash
=
kh_int_hash_func
(
mrb
,
sym
);
hash
=
kh_int_hash_func
(
mrb
,
sym
);
#ifdef MRB_USE_INLINE_METHOD_CACHE
#ifdef MRB_USE_INLINE_METHOD_CACHE
size_t
cpos
=
(
hash
^
(
uintptr_t
)
t
)
%
MT_CACHE_SIZE
;
size_t
cpos
=
(
hash
^
(
uintptr_t
)
t
)
%
MT_CACHE_SIZE
;
...
@@ -156,22 +158,22 @@ mt_get(mrb_state *mrb, mt_tbl *t, mrb_sym sym)
...
@@ -156,22 +158,22 @@ mt_get(mrb_state *mrb, mt_tbl *t, mrb_sym sym)
#endif
#endif
start
=
pos
=
hash
&
(
t
->
alloc
-
1
);
start
=
pos
=
hash
&
(
t
->
alloc
-
1
);
for
(;;)
{
for
(;;)
{
struct
mt_elem
*
slot
=
&
t
->
table
[
pos
];
mrb_sym
key
=
keys
[
pos
];
if
(
MT_KEY_SYM
(
key
)
==
sym
)
{
if
(
slot
->
key
==
sym
)
{
*
pp
=
vals
[
pos
];
#ifdef MRB_USE_INLINE_METHOD_CACHE
#ifdef MRB_USE_INLINE_METHOD_CACHE
if
(
pos
<
0xff
)
{
if
(
pos
<
0xff
)
{
mt_cache
[
cpos
]
=
pos
;
mt_cache
[
cpos
]
=
pos
;
}
}
#endif
#endif
return
slot
;
return
key
;
}
}
else
if
(
slot_empty_p
(
slot
)
)
{
else
if
(
key
==
MT_EMPTY
)
{
return
NULL
;
return
0
;
}
}
pos
=
(
pos
+
1
)
&
(
t
->
alloc
-
1
);
pos
=
(
pos
+
1
)
&
(
t
->
alloc
-
1
);
if
(
pos
==
start
)
{
/* not found */
if
(
pos
==
start
)
{
/* not found */
return
NULL
;
return
0
;
}
}
}
}
}
}
...
@@ -186,18 +188,17 @@ mt_del(mrb_state *mrb, mt_tbl *t, mrb_sym sym)
...
@@ -186,18 +188,17 @@ mt_del(mrb_state *mrb, mt_tbl *t, mrb_sym sym)
if
(
t
->
alloc
==
0
)
return
FALSE
;
if
(
t
->
alloc
==
0
)
return
FALSE
;
if
(
t
->
size
==
0
)
return
FALSE
;
if
(
t
->
size
==
0
)
return
FALSE
;
mrb_sym
*
keys
=
(
mrb_sym
*
)
&
t
->
ptr
[
t
->
alloc
];
hash
=
kh_int_hash_func
(
mrb
,
sym
);
hash
=
kh_int_hash_func
(
mrb
,
sym
);
start
=
pos
=
hash
&
(
t
->
alloc
-
1
);
start
=
pos
=
hash
&
(
t
->
alloc
-
1
);
for
(;;)
{
for
(;;)
{
struct
mt_elem
*
slot
=
&
t
->
table
[
pos
];
mrb_sym
key
=
keys
[
pos
];
if
(
MT_KEY_SYM
(
key
)
==
sym
)
{
if
(
slot
->
key
==
sym
)
{
t
->
size
--
;
t
->
size
--
;
slot
->
key
=
0
;
keys
[
pos
]
=
MT_DELETED
;
slot
->
func_p
=
1
;
return
TRUE
;
return
TRUE
;
}
}
else
if
(
slot_empty_p
(
slot
)
)
{
else
if
(
key
==
MT_EMPTY
)
{
return
FALSE
;
return
FALSE
;
}
}
pos
=
(
pos
+
1
)
&
(
t
->
alloc
-
1
);
pos
=
(
pos
+
1
)
&
(
t
->
alloc
-
1
);
...
@@ -219,11 +220,11 @@ mt_copy(mrb_state *mrb, mt_tbl *t)
...
@@ -219,11 +220,11 @@ mt_copy(mrb_state *mrb, mt_tbl *t)
if
(
t
->
size
==
0
)
return
NULL
;
if
(
t
->
size
==
0
)
return
NULL
;
t2
=
mt_new
(
mrb
);
t2
=
mt_new
(
mrb
);
mrb_sym
*
keys
=
(
mrb_sym
*
)
&
t
->
ptr
[
t
->
alloc
];
union
mt_ptr
*
vals
=
t
->
ptr
;
for
(
i
=
0
;
i
<
t
->
alloc
;
i
++
)
{
for
(
i
=
0
;
i
<
t
->
alloc
;
i
++
)
{
struct
mt_elem
*
slot
=
&
t
->
table
[
i
];
if
(
MT_KEY_P
(
keys
[
i
]))
{
mt_put
(
mrb
,
t2
,
MT_KEY_SYM
(
keys
[
i
]),
MT_KEY_FLG
(
keys
[
i
]),
vals
[
i
]);
if
(
slot
->
key
)
{
mt_put
(
mrb
,
t2
,
slot
->
key
,
slot
->
func_p
,
slot
->
noarg_p
,
slot
->
ptr
);
}
}
}
}
return
t2
;
return
t2
;
...
@@ -233,7 +234,7 @@ mt_copy(mrb_state *mrb, mt_tbl *t)
...
@@ -233,7 +234,7 @@ mt_copy(mrb_state *mrb, mt_tbl *t)
static
void
static
void
mt_free
(
mrb_state
*
mrb
,
mt_tbl
*
t
)
mt_free
(
mrb_state
*
mrb
,
mt_tbl
*
t
)
{
{
mrb_free
(
mrb
,
t
->
table
);
mrb_free
(
mrb
,
t
->
ptr
);
mrb_free
(
mrb
,
t
);
mrb_free
(
mrb
,
t
);
}
}
...
@@ -247,23 +248,24 @@ mrb_mt_foreach(mrb_state *mrb, struct RClass *c, mrb_mt_foreach_func *fn, void *
...
@@ -247,23 +248,24 @@ mrb_mt_foreach(mrb_state *mrb, struct RClass *c, mrb_mt_foreach_func *fn, void *
if
(
t
->
alloc
==
0
)
return
;
if
(
t
->
alloc
==
0
)
return
;
if
(
t
->
size
==
0
)
return
;
if
(
t
->
size
==
0
)
return
;
mrb_sym
*
keys
=
(
mrb_sym
*
)
&
t
->
ptr
[
t
->
alloc
];
union
mt_ptr
*
vals
=
t
->
ptr
;
for
(
i
=
0
;
i
<
t
->
alloc
;
i
++
)
{
for
(
i
=
0
;
i
<
t
->
alloc
;
i
++
)
{
struct
mt_elem
*
slot
=
&
t
->
table
[
i
];
mrb_sym
key
=
keys
[
i
];
if
(
MT_KEY_SYM
(
key
))
{
if
(
slot
->
key
)
{
mrb_method_t
m
;
mrb_method_t
m
;
if
(
slot
->
func_p
)
{
if
(
key
&
MT_FUNC_P
)
{
MRB_METHOD_FROM_FUNC
(
m
,
slot
->
ptr
.
func
);
MRB_METHOD_FROM_FUNC
(
m
,
vals
[
i
]
.
func
);
}
}
else
{
else
{
MRB_METHOD_FROM_PROC
(
m
,
slot
->
ptr
.
proc
);
MRB_METHOD_FROM_PROC
(
m
,
vals
[
i
]
.
proc
);
}
}
if
(
slot
->
noarg_p
)
{
if
(
key
&
MT_NOARG_P
)
{
MRB_METHOD_NOARG_SET
(
m
);
MRB_METHOD_NOARG_SET
(
m
);
}
}
if
(
fn
(
mrb
,
slot
->
key
,
m
,
p
)
!=
0
)
if
(
fn
(
mrb
,
MT_KEY_SYM
(
key
)
,
m
,
p
)
!=
0
)
return
;
return
;
}
}
}
}
...
@@ -280,11 +282,11 @@ mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c)
...
@@ -280,11 +282,11 @@ mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c)
if
(
t
->
alloc
==
0
)
return
;
if
(
t
->
alloc
==
0
)
return
;
if
(
t
->
size
==
0
)
return
;
if
(
t
->
size
==
0
)
return
;
mrb_sym
*
keys
=
(
mrb_sym
*
)
&
t
->
ptr
[
t
->
alloc
];
union
mt_ptr
*
vals
=
t
->
ptr
;
for
(
i
=
0
;
i
<
t
->
alloc
;
i
++
)
{
for
(
i
=
0
;
i
<
t
->
alloc
;
i
++
)
{
struct
mt_elem
*
slot
=
&
t
->
table
[
i
];
if
(
MT_KEY_P
(
keys
[
i
])
&&
(
keys
[
i
]
&
MT_FUNC_P
)
==
0
)
{
/* Proc pointer */
struct
RProc
*
p
=
vals
[
i
].
proc
;
if
(
slot
->
key
&&
!
slot
->
func_p
)
{
/* Proc pointer */
struct
RProc
*
p
=
slot
->
ptr
.
proc
;
mrb_gc_mark
(
mrb
,
(
struct
RBasic
*
)
p
);
mrb_gc_mark
(
mrb
,
(
struct
RBasic
*
)
p
);
}
}
}
}
...
@@ -769,7 +771,7 @@ mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_method_
...
@@ -769,7 +771,7 @@ mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_method_
else
{
else
{
ptr
.
func
=
MRB_METHOD_FUNC
(
m
);
ptr
.
func
=
MRB_METHOD_FUNC
(
m
);
}
}
mt_put
(
mrb
,
h
,
mid
,
M
RB_METHOD_FUNC_P
(
m
),
MRB_METHOD_NOARG_P
(
m
),
ptr
);
mt_put
(
mrb
,
h
,
mid
,
M
T_FLAGS
(
MRB_METHOD_FUNC_P
(
m
),
MRB_METHOD_NOARG_P
(
m
)
),
ptr
);
mc_clear
(
mrb
);
mc_clear
(
mrb
);
}
}
...
@@ -1782,17 +1784,18 @@ mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid)
...
@@ -1782,17 +1784,18 @@ mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid)
mt_tbl
*
h
=
c
->
mt
;
mt_tbl
*
h
=
c
->
mt
;
if
(
h
)
{
if
(
h
)
{
struct
mt_elem
*
e
=
mt_get
(
mrb
,
h
,
mid
);
union
mt_ptr
ptr
;
if
(
e
)
{
mrb_sym
ret
=
mt_get
(
mrb
,
h
,
mid
,
&
ptr
);
if
(
e
->
ptr
.
proc
==
0
)
break
;
if
(
ret
)
{
if
(
ptr
.
proc
==
0
)
break
;
*
cp
=
c
;
*
cp
=
c
;
if
(
e
->
func_p
)
{
if
(
ret
&
MT_FUNC_P
)
{
MRB_METHOD_FROM_FUNC
(
m
,
e
->
ptr
.
func
);
MRB_METHOD_FROM_FUNC
(
m
,
ptr
.
func
);
}
}
else
{
else
{
MRB_METHOD_FROM_PROC
(
m
,
e
->
ptr
.
proc
);
MRB_METHOD_FROM_PROC
(
m
,
ptr
.
proc
);
}
}
if
(
e
->
noarg_p
)
{
if
(
ret
&
MT_NOARG_P
)
{
MRB_METHOD_NOARG_SET
(
m
);
MRB_METHOD_NOARG_SET
(
m
);
}
}
#ifndef MRB_NO_METHOD_CACHE
#ifndef MRB_NO_METHOD_CACHE
...
...
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