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 {
mrb_func_t
func
;
};
struct
mt_elem
{
union
mt_ptr
ptr
;
size_t
func_p
:
1
;
size_t
noarg_p
:
1
;
mrb_sym
key
:
sizeof
(
mrb_sym
)
*
8
-
2
;
};
#define MT_KEY_P(k) (((k)>>2) != 0)
#define MT_FUNC_P 1
#define MT_NOARG_P 2
#define MT_EMPTY 0
#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 */
typedef
struct
mt_tbl
{
size_t
size
;
size_t
alloc
;
struct
mt_elem
*
table
;
union
mt_ptr
*
ptr
;
}
mt_tbl
;
#ifdef MRB_USE_INLINE_METHOD_CACHE
...
...
@@ -51,101 +55,99 @@ mt_new(mrb_state *mrb)
t
=
(
mt_tbl
*
)
mrb_malloc
(
mrb
,
sizeof
(
mt_tbl
));
t
->
size
=
0
;
t
->
alloc
=
0
;
t
->
table
=
NULL
;
t
->
ptr
=
NULL
;
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
mt_rehash
(
mrb_state
*
mrb
,
mt_tbl
*
t
)
{
size_t
old_alloc
=
t
->
alloc
;
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
);
if
(
old_alloc
==
new_alloc
)
return
;
t
->
alloc
=
new_alloc
;
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
++
)
{
struct
mt_elem
*
slot
=
&
old_table
[
i
];
/* key = 0 means empty or deleted */
if
(
slot
->
key
!=
0
)
{
mt_put
(
mrb
,
t
,
slot
->
key
,
slot
->
func_p
,
slot
->
noarg_p
,
slot
->
ptr
);
mrb_sym
key
=
keys
[
i
];
if
(
MT_KEY_P
(
key
))
{
mt_put
(
mrb
,
t
,
MT_KEY_SYM
(
key
),
MT_KEY_FLG
(
key
),
vals
[
i
]);
}
}
mrb_free
(
mrb
,
old_
table
);
mrb_free
(
mrb
,
old_
ptr
);
}
#define slot_empty_p(slot) ((slot)->key == 0 && (slot)->func_p == 0)
/* Set the value for the symbol in the method table. */
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
)
{
size_t
hash
,
pos
,
start
;
s
truct
mt_elem
*
dslot
=
NULL
;
s
size_t
dpos
=
-
1
;
if
(
t
->
alloc
==
0
)
{
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
);
start
=
pos
=
hash
&
(
t
->
alloc
-
1
);
for
(;;)
{
struct
mt_elem
*
slot
=
&
t
->
table
[
pos
];
if
(
slot
->
key
==
sym
)
{
slot
->
func_p
=
func_p
;
slot
->
noarg_p
=
noarg_p
;
slot
->
ptr
=
ptr
;
return
slot
;
mrb_sym
key
=
keys
[
pos
];
if
(
MT_KEY_SYM
(
key
)
==
sym
)
{
value_set:
keys
[
pos
]
=
MT_KEY
(
sym
,
flags
);
vals
[
pos
]
=
ptr
;
return
;
}
else
if
(
slot
->
key
==
0
)
{
/* empty or deleted */
if
(
slot
->
func_p
==
0
)
{
/* empty */
t
->
size
++
;
slot
->
key
=
sym
;
slot
->
func_p
=
func_p
;
slot
->
noarg_p
=
noarg_p
;
slot
->
ptr
=
ptr
;
return
slot
;
}
else
if
(
!
dslot
)
{
/* deleted */
dslot
=
slot
;
}
else
if
(
key
==
MT_EMPTY
)
{
t
->
size
++
;
goto
value_set
;
}
else
if
(
key
==
MT_DELETED
&&
dpos
<
0
)
{
dpos
=
pos
;
}
pos
=
(
pos
+
1
)
&
(
t
->
alloc
-
1
);
if
(
pos
==
start
)
{
/* not found */
if
(
d
slot
)
{
if
(
d
pos
>
0
)
{
t
->
size
++
;
dslot
->
key
=
sym
;
dslot
->
func_p
=
func_p
;
dslot
->
noarg_p
=
noarg_p
;
dslot
->
ptr
=
ptr
;
return
dslot
;
pos
=
dpos
;
goto
value_set
;
}
/* no room */
mt_rehash
(
mrb
,
t
);
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. */
static
struct
mt_elem
*
mt_get
(
mrb_state
*
mrb
,
mt_tbl
*
t
,
mrb_sym
sym
)
static
mrb_sym
mt_get
(
mrb_state
*
mrb
,
mt_tbl
*
t
,
mrb_sym
sym
,
union
mt_ptr
*
pp
)
{
size_t
hash
,
pos
,
start
;
if
(
t
==
NULL
)
return
NULL
;
if
(
t
->
alloc
==
0
)
return
NULL
;
if
(
t
->
size
==
0
)
return
NULL
;
if
(
t
==
NULL
)
return
0
;
if
(
t
->
alloc
==
0
)
return
0
;
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
);
#ifdef MRB_USE_INLINE_METHOD_CACHE
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)
#endif
start
=
pos
=
hash
&
(
t
->
alloc
-
1
);
for
(;;)
{
struct
mt_elem
*
slot
=
&
t
->
table
[
pos
];
if
(
slot
->
key
==
sym
)
{
mrb_sym
key
=
keys
[
pos
];
if
(
MT_KEY_SYM
(
key
)
==
sym
)
{
*
pp
=
vals
[
pos
];
#ifdef MRB_USE_INLINE_METHOD_CACHE
if
(
pos
<
0xff
)
{
mt_cache
[
cpos
]
=
pos
;
}
#endif
return
slot
;
return
key
;
}
else
if
(
slot_empty_p
(
slot
)
)
{
return
NULL
;
else
if
(
key
==
MT_EMPTY
)
{
return
0
;
}
pos
=
(
pos
+
1
)
&
(
t
->
alloc
-
1
);
if
(
pos
==
start
)
{
/* not found */
return
NULL
;
return
0
;
}
}
}
...
...
@@ -186,18 +188,17 @@ mt_del(mrb_state *mrb, mt_tbl *t, mrb_sym sym)
if
(
t
->
alloc
==
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
);
start
=
pos
=
hash
&
(
t
->
alloc
-
1
);
for
(;;)
{
struct
mt_elem
*
slot
=
&
t
->
table
[
pos
];
if
(
slot
->
key
==
sym
)
{
mrb_sym
key
=
keys
[
pos
];
if
(
MT_KEY_SYM
(
key
)
==
sym
)
{
t
->
size
--
;
slot
->
key
=
0
;
slot
->
func_p
=
1
;
keys
[
pos
]
=
MT_DELETED
;
return
TRUE
;
}
else
if
(
slot_empty_p
(
slot
)
)
{
else
if
(
key
==
MT_EMPTY
)
{
return
FALSE
;
}
pos
=
(
pos
+
1
)
&
(
t
->
alloc
-
1
);
...
...
@@ -219,11 +220,11 @@ mt_copy(mrb_state *mrb, mt_tbl *t)
if
(
t
->
size
==
0
)
return
NULL
;
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
++
)
{
struct
mt_elem
*
slot
=
&
t
->
table
[
i
];
if
(
slot
->
key
)
{
mt_put
(
mrb
,
t2
,
slot
->
key
,
slot
->
func_p
,
slot
->
noarg_p
,
slot
->
ptr
);
if
(
MT_KEY_P
(
keys
[
i
]))
{
mt_put
(
mrb
,
t2
,
MT_KEY_SYM
(
keys
[
i
]),
MT_KEY_FLG
(
keys
[
i
]),
vals
[
i
]);
}
}
return
t2
;
...
...
@@ -233,7 +234,7 @@ mt_copy(mrb_state *mrb, mt_tbl *t)
static
void
mt_free
(
mrb_state
*
mrb
,
mt_tbl
*
t
)
{
mrb_free
(
mrb
,
t
->
table
);
mrb_free
(
mrb
,
t
->
ptr
);
mrb_free
(
mrb
,
t
);
}
...
...
@@ -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
->
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
++
)
{
struct
mt_elem
*
slot
=
&
t
->
table
[
i
];
if
(
slot
->
key
)
{
mrb_sym
key
=
keys
[
i
];
if
(
MT_KEY_SYM
(
key
))
{
mrb_method_t
m
;
if
(
slot
->
func_p
)
{
MRB_METHOD_FROM_FUNC
(
m
,
slot
->
ptr
.
func
);
if
(
key
&
MT_FUNC_P
)
{
MRB_METHOD_FROM_FUNC
(
m
,
vals
[
i
]
.
func
);
}
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
);
}
if
(
fn
(
mrb
,
slot
->
key
,
m
,
p
)
!=
0
)
if
(
fn
(
mrb
,
MT_KEY_SYM
(
key
)
,
m
,
p
)
!=
0
)
return
;
}
}
...
...
@@ -280,11 +282,11 @@ mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c)
if
(
t
->
alloc
==
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
++
)
{
struct
mt_elem
*
slot
=
&
t
->
table
[
i
];
if
(
slot
->
key
&&
!
slot
->
func_p
)
{
/* Proc pointer */
struct
RProc
*
p
=
slot
->
ptr
.
proc
;
if
(
MT_KEY_P
(
keys
[
i
])
&&
(
keys
[
i
]
&
MT_FUNC_P
)
==
0
)
{
/* Proc pointer */
struct
RProc
*
p
=
vals
[
i
].
proc
;
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_
else
{
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
);
}
...
...
@@ -1782,17 +1784,18 @@ mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid)
mt_tbl
*
h
=
c
->
mt
;
if
(
h
)
{
struct
mt_elem
*
e
=
mt_get
(
mrb
,
h
,
mid
);
if
(
e
)
{
if
(
e
->
ptr
.
proc
==
0
)
break
;
union
mt_ptr
ptr
;
mrb_sym
ret
=
mt_get
(
mrb
,
h
,
mid
,
&
ptr
);
if
(
ret
)
{
if
(
ptr
.
proc
==
0
)
break
;
*
cp
=
c
;
if
(
e
->
func_p
)
{
MRB_METHOD_FROM_FUNC
(
m
,
e
->
ptr
.
func
);
if
(
ret
&
MT_FUNC_P
)
{
MRB_METHOD_FROM_FUNC
(
m
,
ptr
.
func
);
}
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
);
}
#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