Skip to content

Commit 053389d

Browse files
authored
Add info to external pointer free callback. (#4642)
Furthermore reduce memory consumption when only one external pointer is assigned to an object. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
1 parent b3ec217 commit 053389d

28 files changed

+299
-118
lines changed

docs/02.API-REFERENCE.md

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -696,29 +696,57 @@ typedef jerry_value_t (*jerry_external_handler_t) (const jerry_call_info_t *call
696696

697697
- [jerry_create_external_function](#jerry_create_external_function)
698698

699+
## jerry_value_free_callback_t
700+
701+
**Summary**
702+
703+
Native free callback of generic value types.
704+
705+
*Note*:
706+
- Referred values by this method must have at least 1 reference. (Correct API usage satisfies this condition)
707+
708+
**Prototype**
709+
710+
```c
711+
typedef void (*jerry_value_free_callback_t) (void *native_p);
712+
```
713+
714+
*New in version [[NEXT_RELEASE]]*.
715+
716+
**See also**
717+
718+
- [jerry_create_external_string](#jerry_create_external_string)
719+
- [jerry_create_external_string_sz](#jerry_create_external_string_sz)
720+
- [jerry_create_arraybuffer_external](#jerry_create_arraybuffer_external)
721+
699722
## jerry_object_native_free_callback_t
700723

701724
**Summary**
702725

703-
Native free callback of an object. It is used in `jerry_object_native_info_t` and for external Array buffers.
726+
Native free callback of an object. The callback receives both the memory pointer and the type
727+
information passed to [jerry_set_object_native_pointer](#jerry_set_object_native_pointer).
704728

705729
*Note*:
706730
- Referred values by this method must have at least 1 reference. (Correct API usage satisfies this condition)
707731

708732
**Prototype**
709733

710734
```c
711-
typedef void (*jerry_object_native_free_callback_t) (void *native_p);
735+
typedef void (*jerry_object_native_free_callback_t) (void *native_p, struct jerry_object_native_info_t *info_p);
712736
```
713737

738+
- `native_p` - native pointer passed to [jerry_set_object_native_pointer](#jerry_set_object_native_pointer).
739+
- `info_p` - native type info passed to [jerry_set_object_native_pointer](#jerry_set_object_native_pointer).
740+
714741
*New in version 2.0*: Renamed from `jerry_object_free_callback_t`.
715742

716743
*Changed in version 2.2*: API calls are once again allowed. (See note)
717744

745+
*Changed in version [[NEXT_RELEASE]]*: `info_p` argument is added
746+
718747
**See also**
719748

720749
- [jerry_object_native_info_t](#jerry_object_native_info_t)
721-
- [jerry_create_arraybuffer_external](#jerry_create_arraybuffer_external)
722750

723751
## jerry_error_object_created_callback_t
724752

@@ -5655,7 +5683,7 @@ so the user can release the buffer which was provided.
56555683
jerry_value_t
56565684
jerry_create_arraybuffer_external (const jerry_length_t size
56575685
uint8_t *buffer_p,
5658-
jerry_object_native_free_callback_t free_cb);
5686+
jerry_value_free_callback_t free_cb);
56595687
```
56605688

56615689
- `size` - size of the buffer to use **in bytes** (should not be 0)
@@ -5667,6 +5695,8 @@ jerry_create_arraybuffer_external (const jerry_length_t size
56675695

56685696
*New in version 2.0*.
56695697

5698+
*Changed in version [[NEXT_RELEASE]]*: type of `free_cb` has been changed.
5699+
56705700
**Example**
56715701

56725702
```c
@@ -6473,7 +6503,7 @@ is no longer needed.
64736503
```c
64746504
jerry_value_t
64756505
jerry_create_external_string (const jerry_char_t *str_p,
6476-
jerry_object_native_free_callback_t free_cb)
6506+
jerry_value_free_callback_t free_cb)
64776507
```
64786508

64796509
- `str_p` - non-null pointer to string
@@ -6482,6 +6512,8 @@ jerry_create_external_string (const jerry_char_t *str_p,
64826512

64836513
*New in version 2.4*.
64846514

6515+
*Changed in version [[NEXT_RELEASE]]*: type of `free_cb` has been changed.
6516+
64856517
**Example**
64866518

64876519
```c
@@ -6519,7 +6551,7 @@ is no longer needed.
65196551
jerry_value_t
65206552
jerry_create_external_string_sz (const jerry_char_t *str_p,
65216553
jerry_size_t str_size,
6522-
jerry_object_native_free_callback_t free_cb)
6554+
jerry_value_free_callback_t free_cb)
65236555
```
65246556

65256557
- `str_p` - non-null pointer to string
@@ -6529,6 +6561,8 @@ jerry_create_external_string_sz (const jerry_char_t *str_p,
65296561

65306562
*New in version 2.4*.
65316563

6564+
*Changed in version [[NEXT_RELEASE]]*: type of `free_cb` has been changed.
6565+
65326566
**Example**
65336567

65346568
```c
@@ -8416,8 +8450,11 @@ typedef struct
84168450
#define SECRET_INFO ((void *) 42)
84178451

84188452
static void
8419-
buffer_native_freecb (void *native_p)
8453+
buffer_native_freecb (void *native_p,
8454+
jerry_object_native_info_t *info_p)
84208455
{
8456+
(void) info_p;
8457+
84218458
char *data_p = ((buffer_native_object_t*)native_p)->data_p;
84228459

84238460
if (data_p != NULL)
@@ -8429,14 +8466,21 @@ buffer_native_freecb (void *native_p)
84298466
}
84308467

84318468
static void
8432-
shape_native_freecb (void *native_p)
8469+
shape_native_freecb (void *native_p,
8470+
jerry_object_native_info_t *info_p)
84338471
{
8472+
(void) info_p;
8473+
84348474
free (native_p);
84358475
}
84368476

84378477
static void
8438-
destructor_freecb (void *native_p)
8478+
destructor_freecb (void *native_p,
8479+
jerry_object_native_info_t *info_p)
84398480
{
8481+
(void) native_p;
8482+
(void) info_p;
8483+
84408484
printf("Note: the object has been freed\n");
84418485
}
84428486

@@ -8988,8 +9032,11 @@ typedef struct
89889032
int match_foo_value;
89899033
} find_object_data_t;
89909034

8991-
static void native_freecb (void *native_p)
9035+
static void native_freecb (void *native_p,
9036+
jerry_object_native_info_t *info_p)
89929037
{
9038+
(void) info_p;
9039+
89939040
/* `native_p` was allocated via malloc. */
89949041
free (native_p);
89959042
} /* native_freecb */

jerry-core/api/jerry.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2474,7 +2474,7 @@ jerry_create_string_sz (const jerry_char_t *str_p, /**< pointer to string */
24742474
*/
24752475
jerry_value_t
24762476
jerry_create_external_string (const jerry_char_t *str_p, /**< pointer to string */
2477-
jerry_object_native_free_callback_t free_cb) /**< free callback */
2477+
jerry_value_free_callback_t free_cb) /**< free callback */
24782478
{
24792479
return jerry_create_external_string_sz (str_p, lit_zt_utf8_string_size ((lit_utf8_byte_t *) str_p), free_cb);
24802480
} /* jerry_create_external_string */
@@ -2490,7 +2490,7 @@ jerry_create_external_string (const jerry_char_t *str_p, /**< pointer to string
24902490
jerry_value_t
24912491
jerry_create_external_string_sz (const jerry_char_t *str_p, /**< pointer to string */
24922492
jerry_size_t str_size, /**< string size */
2493-
jerry_object_native_free_callback_t free_cb) /**< free callback */
2493+
jerry_value_free_callback_t free_cb) /**< free callback */
24942494
{
24952495
jerry_assert_api_available ();
24962496

@@ -4022,7 +4022,7 @@ jerry_objects_foreach_by_native_info (const jerry_object_native_info_t *native_i
40224022
{
40234023
native_pointer_p = ecma_get_native_pointer_value (iter_p, (void *) native_info_p);
40244024
if (native_pointer_p
4025-
&& !foreach_p (ecma_make_object_value (iter_p), native_pointer_p->data_p, user_data_p))
4025+
&& !foreach_p (ecma_make_object_value (iter_p), native_pointer_p->native_p, user_data_p))
40264026
{
40274027
return true;
40284028
}
@@ -4066,7 +4066,7 @@ jerry_get_object_native_pointer (const jerry_value_t obj_val, /**< object to get
40664066

40674067
if (out_native_pointer_p != NULL)
40684068
{
4069-
*out_native_pointer_p = native_pointer_p->data_p;
4069+
*out_native_pointer_p = native_pointer_p->native_p;
40704070
}
40714071

40724072
return true;
@@ -5209,7 +5209,7 @@ jerry_create_arraybuffer (const jerry_length_t size) /**< size of the ArrayBuffe
52095209
jerry_value_t
52105210
jerry_create_arraybuffer_external (const jerry_length_t size, /**< size of the buffer to used */
52115211
uint8_t *buffer_p, /**< buffer to use as the ArrayBuffer's backing */
5212-
jerry_object_native_free_callback_t free_cb) /**< buffer free callback */
5212+
jerry_value_free_callback_t free_cb) /**< buffer free callback */
52135213
{
52145214
jerry_assert_api_available ();
52155215

@@ -5222,9 +5222,7 @@ jerry_create_arraybuffer_external (const jerry_length_t size, /**< size of the b
52225222
}
52235223
else
52245224
{
5225-
arraybuffer = ecma_arraybuffer_new_object_external (size,
5226-
buffer_p,
5227-
(ecma_object_native_free_callback_t) free_cb);
5225+
arraybuffer = ecma_arraybuffer_new_object_external (size, buffer_p, free_cb);
52285226
}
52295227

52305228
return jerry_return (ecma_make_object_value (arraybuffer));

jerry-core/ecma/base/ecma-gc.c

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,37 +1175,54 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
11751175
* Free the native handle/pointer by calling its free callback.
11761176
*/
11771177
static void
1178-
ecma_gc_free_native_pointer (ecma_value_t value) /**< property value */
1178+
ecma_gc_free_native_pointer (ecma_property_t property, /**< property descriptor */
1179+
ecma_value_t value) /**< property value */
11791180
{
1180-
if (value == JMEM_CP_NULL)
1181+
if (JERRY_LIKELY (property & ECMA_PROPERTY_FLAG_SINGLE_EXTERNAL))
11811182
{
1183+
JERRY_ASSERT (value != JMEM_CP_NULL);
1184+
1185+
ecma_native_pointer_t *native_pointer_p;
1186+
native_pointer_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_native_pointer_t, value);
1187+
1188+
jerry_object_native_free_callback_t free_cb = native_pointer_p->info_p->free_cb;
1189+
1190+
if (free_cb != NULL)
1191+
{
1192+
free_cb (native_pointer_p->native_p, native_pointer_p->info_p);
1193+
}
1194+
1195+
jmem_heap_free_block (native_pointer_p, sizeof (ecma_native_pointer_t));
11821196
return;
11831197
}
11841198

1185-
ecma_native_pointer_t *native_pointer_p;
1199+
if (value == JMEM_CP_NULL)
1200+
{
1201+
return;
1202+
}
11861203

1187-
native_pointer_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_native_pointer_t, value);
1188-
JERRY_ASSERT (native_pointer_p != NULL);
1204+
ecma_native_pointer_chain_t *item_p;
1205+
item_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_native_pointer_chain_t, value);
11891206

11901207
do
11911208
{
1192-
if (native_pointer_p->info_p != NULL)
1209+
if (item_p->data.info_p != NULL)
11931210
{
1194-
ecma_object_native_free_callback_t free_cb = native_pointer_p->info_p->free_cb;
1211+
jerry_object_native_free_callback_t free_cb = item_p->data.info_p->free_cb;
11951212

11961213
if (free_cb != NULL)
11971214
{
1198-
free_cb (native_pointer_p->data_p);
1215+
free_cb (item_p->data.native_p, item_p->data.info_p);
11991216
}
12001217
}
12011218

1202-
ecma_native_pointer_t *next_p = native_pointer_p->next_p;
1219+
ecma_native_pointer_chain_t *next_p = item_p->next_p;
12031220

1204-
jmem_heap_free_block (native_pointer_p, sizeof (ecma_native_pointer_t));
1221+
jmem_heap_free_block (item_p, sizeof (ecma_native_pointer_chain_t));
12051222

1206-
native_pointer_p = next_p;
1223+
item_p = next_p;
12071224
}
1208-
while (native_pointer_p != NULL);
1225+
while (item_p != NULL);
12091226
} /* ecma_gc_free_native_pointer */
12101227

12111228
/**
@@ -1518,7 +1535,7 @@ ecma_gc_free_property (ecma_object_t *object_p, /**< object */
15181535
default:
15191536
{
15201537
JERRY_ASSERT (name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER);
1521-
ecma_gc_free_native_pointer (value);
1538+
ecma_gc_free_native_pointer (property, value);
15221539
break;
15231540
}
15241541
}

jerry-core/ecma/base/ecma-globals.h

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -299,27 +299,22 @@ typedef ecma_value_t (*ecma_native_handler_t) (const struct jerry_call_info_t *c
299299
const uint32_t args_count);
300300

301301
/**
302-
* Native free callback of an object.
303-
*/
304-
typedef void (*ecma_object_native_free_callback_t) (void *native_p);
305-
306-
/**
307-
* Type information of a native pointer.
302+
* Representation of native pointer data.
308303
*/
309304
typedef struct
310305
{
311-
ecma_object_native_free_callback_t free_cb; /**< the free callback of the native pointer */
312-
} ecma_object_native_info_t;
306+
void *native_p; /**< points to the data of the object */
307+
jerry_object_native_info_t *info_p; /**< native info */
308+
} ecma_native_pointer_t;
313309

314310
/**
315-
* Representation for native pointer data.
311+
* Representation of native pointer data chain.
316312
*/
317-
typedef struct ecma_native_pointer_t
313+
typedef struct ecma_native_pointer_chain_t
318314
{
319-
void *data_p; /**< points to the data of the object */
320-
ecma_object_native_info_t *info_p; /**< native info */
321-
struct ecma_native_pointer_t *next_p; /**< points to the next ecma_native_pointer_t element */
322-
} ecma_native_pointer_t;
315+
ecma_native_pointer_t data; /**< pointer data */
316+
struct ecma_native_pointer_chain_t *next_p; /**< next in the list */
317+
} ecma_native_pointer_chain_t;
323318

324319
/**
325320
* Option bits for ecma_parse_options_t.
@@ -415,7 +410,7 @@ typedef enum
415410
ECMA_PROPERTY_FLAG_CONFIGURABLE = (1u << 0), /**< property is configurable */
416411
ECMA_PROPERTY_FLAG_ENUMERABLE = (1u << 1), /**< property is enumerable */
417412
ECMA_PROPERTY_FLAG_WRITABLE = (1u << 2), /**< property is writable */
418-
413+
ECMA_PROPERTY_FLAG_SINGLE_EXTERNAL = (1u << 2), /**< only one external pointer is assigned to this object */
419414
ECMA_PROPERTY_FLAG_DELETED = (1u << 3), /**< property is deleted */
420415
ECMA_FAST_ARRAY_FLAG = (1u << 3), /**< array is fast array */
421416
ECMA_PROPERTY_FLAG_LCACHED = (1u << 4), /**< property is lcached */
@@ -1849,7 +1844,7 @@ typedef struct
18491844
typedef struct
18501845
{
18511846
ecma_long_string_t header;
1852-
ecma_object_native_free_callback_t free_cb; /**< free callback */
1847+
jerry_value_free_callback_t free_cb; /**< free callback */
18531848
} ecma_external_string_t;
18541849

18551850
/**
@@ -2101,7 +2096,7 @@ typedef struct
21012096
{
21022097
ecma_extended_object_t extended_object; /**< extended object part */
21032098
void *buffer_p; /**< external buffer pointer */
2104-
ecma_object_native_free_callback_t free_cb; /**< the free callback for the above buffer pointer */
2099+
jerry_value_free_callback_t free_cb; /**< the free callback for the above buffer pointer */
21052100
} ecma_arraybuffer_external_info;
21062101

21072102
/**

0 commit comments

Comments
 (0)