diff options
author | Peter Zhu <peter@peterzhu.ca> | 2022-12-23 09:33:51 -0500 |
---|---|---|
committer | Peter Zhu <peter@peterzhu.ca> | 2022-12-23 11:21:14 -0500 |
commit | 7891f9407184ca6b4636092555d2546e3830c2ff (patch) | |
tree | 0f49dff240166db2b96fd5b81fecadf7cbc1e1d0 /array.c | |
parent | d61a4cec618b8f5554398fff2ee4656763aeec4e (diff) |
Don't allow re-embedding frozen arrays
Frozen arrays should not move from heap allocated to embedded because
frozen arrays could be shared roots for other (shared) arrays. If the
frozen array moves from heap allocated to embedded it would cause issues
since the shared array would no longer know where to set the pointer
in the shared root.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/7013
Diffstat (limited to 'array.c')
-rw-r--r-- | array.c | 11 |
1 files changed, 9 insertions, 2 deletions
@@ -226,8 +226,15 @@ ary_embeddable_p(long capa) bool rb_ary_embeddable_p(VALUE ary) { - // if the array is shared or a shared root then it's not moveable - return !(ARY_SHARED_P(ary) || ARY_SHARED_ROOT_P(ary)); + /* An array cannot be turned embeddable when the array is: + * - Shared root: other objects may point to the buffer of this array + * so we cannot make it embedded. + * - Frozen: this array may also be a shared root without the shared root + * flag. + * - Shared: we don't want to re-embed an array that points to a shared + * root (to save memory). + */ + return !(ARY_SHARED_ROOT_P(ary) || OBJ_FROZEN(ary) || ARY_SHARED_P(ary)); } size_t |