@@ -293,6 +293,7 @@ ecma_gc_mark_promise_object (ecma_extended_object_t *ext_object_p) /**< extended
293
293
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
294
294
295
295
#if ENABLED (JERRY_ES2015_BUILTIN_CONTAINER )
296
+
296
297
/**
297
298
* Mark objects referenced by Map/Set built-in.
298
299
*/
@@ -359,6 +360,73 @@ ecma_gc_mark_container_object (ecma_object_t *object_p) /**< object */
359
360
360
361
#endif /* ENABLED (JERRY_ES2015_BUILTIN_CONTAINER) */
361
362
363
+ #if ENABLED (JERRY_ES2015 )
364
+
365
+ /**
366
+ * Mark objects referenced by inactive generator functions, async functions, etc.
367
+ */
368
+ static void
369
+ ecma_gc_mark_executable_object (ecma_object_t * object_p ) /**< object */
370
+ {
371
+ vm_executable_object_t * executable_object_p = (vm_executable_object_t * ) object_p ;
372
+
373
+ if (!ECMA_EXECUTABLE_OBJECT_IS_SUSPENDED (executable_object_p -> extended_object .u .class_prop .extra_info ))
374
+ {
375
+ /* All objects referenced by running executable objects are strong roots,
376
+ * and a finished executable object cannot refer to other values. */
377
+ return ;
378
+ }
379
+
380
+ ecma_gc_set_object_visited (executable_object_p -> frame_ctx .lex_env_p );
381
+
382
+ if (ecma_is_value_object (executable_object_p -> frame_ctx .this_binding ))
383
+ {
384
+ ecma_gc_set_object_visited (ecma_get_object_from_value (executable_object_p -> frame_ctx .this_binding ));
385
+ }
386
+
387
+ const ecma_compiled_code_t * bytecode_header_p = executable_object_p -> frame_ctx .bytecode_header_p ;
388
+ size_t register_end ;
389
+
390
+ if (bytecode_header_p -> status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS )
391
+ {
392
+ cbc_uint16_arguments_t * args_p = (cbc_uint16_arguments_t * ) bytecode_header_p ;
393
+ register_end = args_p -> register_end ;
394
+ }
395
+ else
396
+ {
397
+ cbc_uint8_arguments_t * args_p = (cbc_uint8_arguments_t * ) bytecode_header_p ;
398
+ register_end = args_p -> register_end ;
399
+ }
400
+
401
+ ecma_value_t * register_p = VM_GET_REGISTERS (& executable_object_p -> frame_ctx );
402
+ ecma_value_t * register_end_p = register_p + register_end ;
403
+
404
+ while (register_p < register_end_p )
405
+ {
406
+ if (ecma_is_value_object (* register_p ))
407
+ {
408
+ ecma_gc_set_object_visited (ecma_get_object_from_value (* register_p ));
409
+ }
410
+
411
+ register_p ++ ;
412
+ }
413
+
414
+ register_p += executable_object_p -> frame_ctx .context_depth ;
415
+ register_end_p = executable_object_p -> frame_ctx .stack_top_p ;
416
+
417
+ while (register_p < register_end_p )
418
+ {
419
+ if (ecma_is_value_object (* register_p ))
420
+ {
421
+ ecma_gc_set_object_visited (ecma_get_object_from_value (* register_p ));
422
+ }
423
+
424
+ register_p ++ ;
425
+ }
426
+ } /* ecma_gc_mark_executable_object */
427
+
428
+ #endif /* ENABLED (JERRY_ES2015) */
429
+
362
430
/**
363
431
* Mark objects as visited starting from specified object as root
364
432
*/
@@ -435,6 +503,13 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
435
503
break ;
436
504
}
437
505
#endif /* ENABLED (JERRY_ES2015_BUILTIN_CONTAINER) */
506
+ #if ENABLED (JERRY_ES2015 )
507
+ case LIT_MAGIC_STRING_GENERATOR_UL :
508
+ {
509
+ ecma_gc_mark_executable_object (object_p );
510
+ break ;
511
+ }
512
+ #endif /* ENABLED (JERRY_ES2015) */
438
513
default :
439
514
{
440
515
break ;
@@ -641,6 +716,100 @@ ecma_free_fast_access_array (ecma_object_t *object_p) /**< fast access mode arra
641
716
ecma_dealloc_extended_object (object_p , sizeof (ecma_extended_object_t ));
642
717
} /* ecma_free_fast_access_array */
643
718
719
+ #if ENABLED (JERRY_ES2015 )
720
+
721
+ /**
722
+ * Free non-objects referenced by inactive generator functions, async functions, etc.
723
+ *
724
+ * @return total object size
725
+ */
726
+ static size_t
727
+ ecma_gc_free_executable_object (ecma_object_t * object_p ) /**< object */
728
+ {
729
+ vm_executable_object_t * executable_object_p = (vm_executable_object_t * ) object_p ;
730
+
731
+ const ecma_compiled_code_t * bytecode_header_p = executable_object_p -> frame_ctx .bytecode_header_p ;
732
+ size_t size , register_end ;
733
+
734
+ if (bytecode_header_p -> status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS )
735
+ {
736
+ cbc_uint16_arguments_t * args_p = (cbc_uint16_arguments_t * ) bytecode_header_p ;
737
+
738
+ register_end = args_p -> register_end ;
739
+ size = (register_end + (size_t ) args_p -> stack_limit ) * sizeof (ecma_value_t );
740
+ }
741
+ else
742
+ {
743
+ cbc_uint8_arguments_t * args_p = (cbc_uint8_arguments_t * ) bytecode_header_p ;
744
+
745
+ register_end = args_p -> register_end ;
746
+ size = (register_end + (size_t ) args_p -> stack_limit ) * sizeof (ecma_value_t );
747
+ }
748
+
749
+ size = JERRY_ALIGNUP (sizeof (vm_executable_object_t ) + size , sizeof (uintptr_t ));
750
+
751
+ JERRY_ASSERT (!(executable_object_p -> extended_object .u .class_prop .extra_info & ECMA_EXECUTABLE_OBJECT_RUNNING ));
752
+
753
+ ecma_bytecode_deref ((ecma_compiled_code_t * ) bytecode_header_p );
754
+
755
+ if (executable_object_p -> extended_object .u .class_prop .extra_info & ECMA_EXECUTABLE_OBJECT_COMPLETED )
756
+ {
757
+ return size ;
758
+ }
759
+
760
+ ecma_free_value_if_not_object (executable_object_p -> frame_ctx .this_binding );
761
+
762
+ ecma_value_t * register_p = VM_GET_REGISTERS (& executable_object_p -> frame_ctx );
763
+ ecma_value_t * register_end_p = register_p + register_end ;
764
+
765
+ while (register_p < register_end_p )
766
+ {
767
+ ecma_free_value_if_not_object (* register_p ++ );
768
+ }
769
+
770
+ if (executable_object_p -> frame_ctx .context_depth > 0 )
771
+ {
772
+ ecma_value_t * context_end_p = register_p ;
773
+
774
+ register_p += executable_object_p -> frame_ctx .context_depth ;
775
+
776
+ ecma_value_t * context_top_p = register_p ;
777
+
778
+ do
779
+ {
780
+ context_top_p [-1 ] &= (uint32_t ) ~VM_CONTEXT_HAS_LEX_ENV ;
781
+
782
+ uint32_t offsets = vm_get_context_value_offsets (context_top_p );
783
+
784
+ while (VM_CONTEXT_HAS_NEXT_OFFSET (offsets ))
785
+ {
786
+ int32_t offset = VM_CONTEXT_GET_NEXT_OFFSET (offsets );
787
+
788
+ if (ecma_is_value_object (context_top_p [offset ]))
789
+ {
790
+ context_top_p [offset ] = ECMA_VALUE_UNDEFINED ;
791
+ }
792
+
793
+ offsets >>= VM_CONTEXT_OFFSET_SHIFT ;
794
+ }
795
+
796
+ context_top_p = vm_stack_context_abort (& executable_object_p -> frame_ctx , context_top_p );
797
+ }
798
+ while (context_top_p > context_end_p );
799
+ }
800
+
801
+ register_end_p = executable_object_p -> frame_ctx .stack_top_p ;
802
+
803
+ while (register_p < register_end_p )
804
+ {
805
+ ecma_free_value_if_not_object (* register_p ++ );
806
+ }
807
+
808
+ return size ;
809
+ } /* ecma_gc_free_executable_object */
810
+
811
+ #endif /* ENABLED (JERRY_ES2015) */
812
+
644
813
/**
645
814
* Free properties of an object
646
815
*/
@@ -930,6 +1099,13 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
930
1099
break ;
931
1100
}
932
1101
#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) */
1102
+ #if ENABLED (JERRY_ES2015 )
1103
+ case LIT_MAGIC_STRING_GENERATOR_UL :
1104
+ {
1105
+ ext_object_size = ecma_gc_free_executable_object (object_p );
1106
+ break ;
1107
+ }
1108
+ #endif /* ENABLED (JERRY_ES2015) */
933
1109
default :
934
1110
{
935
1111
/* The undefined id represents an uninitialized class. */
0 commit comments