<commit_before>/*
Copyright (C) 2001-2009, Parrot Foundation.
$Id$

=head1 NAME

src/sub.c - Subroutines

=head1 DESCRIPTION

Subroutines, continuations, co-routines and other fun stuff...

=head2 Functions

=over 4

=cut

*/

#include "parrot/parrot.h"
#include "parrot/oplib/ops.h"
#include "sub.str"
#include "pmc/pmc_sub.h"
#include "pmc/pmc_continuation.h"

/* HEADERIZER HFILE: include/parrot/sub.h */


/*

=item C<void mark_context_start(void)>

Indicate that a new round of context marking is about to take place.

=cut

*/

static int context_gc_mark = 0;

void
mark_context_start(void)
{
    ASSERT_ARGS(mark_context_start)
    if (++context_gc_mark == 0) context_gc_mark = 1;
}


/*

=item C<void mark_context(PARROT_INTERP, Parrot_Context* ctx)>

Marks the context C<*ctx>.

=cut

*/

void
mark_context(PARROT_INTERP, ARGMOD(Parrot_Context* ctx))
{
    ASSERT_ARGS(mark_context)
    PObj *obj;
    int   i;

    if (ctx->gc_mark == context_gc_mark)
        return;
    ctx->gc_mark = context_gc_mark;

    /* don't mark the context if it's actually dead */
    if (ctx->ref_count < 0) {
        /* report it, though */
        if (Interp_debug_TEST(interp, PARROT_CTX_DESTROY_DEBUG_FLAG)) {
            fprintf(stderr, "[attempt to mark dead context %p]\n",
                (void *)ctx);
        }
        return;
    }

    obj = (PObj *)ctx->current_sub;
    if (obj)
        Parrot_gc_mark_PObj_alive(interp, obj);

    obj = (PObj *)ctx->current_object;
    if (obj)
        Parrot_gc_mark_PObj_alive(interp, obj);

    obj = (PObj *)ctx->current_cont;
    if (obj && !PObj_live_TEST(obj))
        Parrot_gc_mark_PObj_alive(interp, obj);

    if (ctx->caller_ctx)
        mark_context(interp, ctx->caller_ctx);

    if (ctx->outer_ctx)
        mark_context(interp, ctx->outer_ctx);

    obj = (PObj *)ctx->current_namespace;
    if (obj)
        Parrot_gc_mark_PObj_alive(interp, obj);

    obj = (PObj *)ctx->lex_pad;
    if (obj)
        Parrot_gc_mark_PObj_alive(interp, obj);

    obj = (PObj *)ctx->handlers;
    if (obj)
        Parrot_gc_mark_PObj_alive(interp, obj);


    if (!ctx->n_regs_used)
        return;

    for (i = 0; i < ctx->n_regs_used[REGNO_PMC]; ++i) {
        obj = (PObj *)CTX_REG_PMC(ctx, i);
        if (obj)
            Parrot_gc_mark_PObj_alive(interp, obj);
    }

    for (i = 0; i < ctx->n_regs_used[REGNO_STR]; ++i) {
        obj = (PObj *)CTX_REG_STR(ctx, i);
        if (obj) {
            /* work around a mysterious segfault-inducing problem we haven't
             * yet tracked down */
            PObj_flag_CLEAR(is_PMC, obj);
            PObj_is_string_SET(obj);
            Parrot_gc_mark_PObj_alive(interp, obj);
        }
    }
}

/*

=item C<Parrot_sub * new_sub(PARROT_INTERP)>
<commit_msg>[gc] IF WE SEE SEGFAULTS IN THE NEXT DAY OR SO, LOOK AT THIS COMMIT. I removed some code that looked unnecessary, with a note that this was a 'work around' for a 'mysterious segfault' thing. If this actually does cause segfaults, we should have a ticket and start collecting information about it.<commit_after>/*
Copyright (C) 2001-2009, Parrot Foundation.
$Id$

=head1 NAME

src/sub.c - Subroutines

=head1 DESCRIPTION

Subroutines, continuations, co-routines and other fun stuff...

=head2 Functions

=over 4

=cut

*/

#include "parrot/parrot.h"
#include "parrot/oplib/ops.h"
#include "sub.str"
#include "pmc/pmc_sub.h"
#include "pmc/pmc_continuation.h"

/* HEADERIZER HFILE: include/parrot/sub.h */


/*

=item C<void mark_context_start(void)>

Indicate that a new round of context marking is about to take place.

=cut

*/

static int context_gc_mark = 0;

void
mark_context_start(void)
{
    ASSERT_ARGS(mark_context_start)
    if (++context_gc_mark == 0) context_gc_mark = 1;
}


/*

=item C<void mark_context(PARROT_INTERP, Parrot_Context* ctx)>

Marks the context C<*ctx>.

=cut

*/

void
mark_context(PARROT_INTERP, ARGMOD(Parrot_Context* ctx))
{
    ASSERT_ARGS(mark_context)
    PObj *obj;
    int   i;

    if (ctx->gc_mark == context_gc_mark)
        return;
    ctx->gc_mark = context_gc_mark;

    /* don't mark the context if it's actually dead */
    if (ctx->ref_count < 0) {
        /* report it, though */
        if (Interp_debug_TEST(interp, PARROT_CTX_DESTROY_DEBUG_FLAG)) {
            fprintf(stderr, "[attempt to mark dead context %p]\n",
                (void *)ctx);
        }
        return;
    }

    obj = (PObj *)ctx->current_sub;
    if (obj)
        Parrot_gc_mark_PObj_alive(interp, obj);

    obj = (PObj *)ctx->current_object;
    if (obj)
        Parrot_gc_mark_PObj_alive(interp, obj);

    obj = (PObj *)ctx->current_cont;
    if (obj && !PObj_live_TEST(obj))
        Parrot_gc_mark_PObj_alive(interp, obj);

    if (ctx->caller_ctx)
        mark_context(interp, ctx->caller_ctx);

    if (ctx->outer_ctx)
        mark_context(interp, ctx->outer_ctx);

    obj = (PObj *)ctx->current_namespace;
    if (obj)
        Parrot_gc_mark_PObj_alive(interp, obj);

    obj = (PObj *)ctx->lex_pad;
    if (obj)
        Parrot_gc_mark_PObj_alive(interp, obj);

    obj = (PObj *)ctx->handlers;
    if (obj)
        Parrot_gc_mark_PObj_alive(interp, obj);


    if (!ctx->n_regs_used)
        return;

    for (i = 0; i < ctx->n_regs_used[REGNO_PMC]; ++i) {
        obj = (PObj *)CTX_REG_PMC(ctx, i);
        if (obj)
            Parrot_gc_mark_PObj_alive(interp, obj);
    }

    for (i = 0; i < ctx->n_regs_used[REGNO_STR]; ++i) {
        obj = (PObj *)CTX_REG_STR(ctx, i);
        if (obj)
            Parrot_gc_mark_PObj_alive(interp, obj);
    }
}

/*

=item C<Parrot_sub * new_sub(PARROT_INTERP)>

{'fraction_non_alphanumeric': 0.12705798138869004, 'fraction_numerical': 0.006442376521116679, 'mean_word_length': 2.851826326671261, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1612224', 'n_tokens_mistral': 2218, 'n_tokens_neox': 2124, 'n_words': 474}