• .net core 的夸代扫描标记card_table的细节分析


    夸代扫描,比如说回收短暂代,但是在短暂代当中有一个被一代引用的变量。

    这个时候可能会造成了这个变量被回收,程序发生不可与之错误。card table 就是为了预防这种情况的一个数组。

    int p = 0;
    int* card_table= &p;
    card_table[0] = 1;
    card_table[1] = 2;
    card_table[2] = 3;

    card_table表在的索引位 card/32,而card为 2的8次方。而值只有两个为零或者为1,4个字节的0xFFFF的宽度

    BOOL gc_heap::find_card(uint32_t* card_table,
    size_t& card,
    size_t card_word_end,
    size_t& end_card)
    {
    uint32_t* last_card_word;
    uint32_t card_word_value;
    uint32_t bit_position;

    // Find the first card which is set
    last_card_word = &card_table [card_word (card)]; // 找到card_table当前索引的地址值,实质上也就是实际地址除以2的13次方之后的值
    bit_position = card_bit (card); // 求余数获取到偏移的bit位
    card_word_value = (*last_card_word) >> bit_position;// 这个实质上是在set_card的时候复原原值的一个过程card_table[word] = (card_table[word] | (1 << card_bit(card)));
    if (!card_word_value)// 如果当前card_table为零,意思是这个宽度为FFFF的位并没有被跨代记录
    {
    bit_position = 0;
    #ifdef CARD_BUNDLE // card 束
    size_t lcw = card_word(card) + 1;// 把实际地址值除以2的13次方之后,加1,挪向下一个地址值
    if (gc_heap::find_card_dword (lcw, card_word_end) == FALSE)// 查找lcw和card_word_end之间是否有被跨代表及
    {
    return FALSE;//没有返回
    }
    else //有的话
    {
    last_card_word = &card_table [lcw];// 设置
    card_word_value = *last_card_word;// 设置
    }

    #else //CARD_BUNDLE.//没有定义card bundle
    do // 循环实际地址值
    {
    ++last_card_word;
    }
    while ((last_card_word < &card_table [card_word_end]) && !(*last_card_word)); // 当找到一个被跨代标记的

    if (last_card_word < &card_table [card_word_end])
    {
    card_word_value = *last_card_word;
    }
    else
    {
    // We failed to find any non-zero card words before we got to card_word_end
    return FALSE;
    }
    #endif //CARD_BUNDLE
    }

    // Look for the lowest bit set
    if (card_word_value)
    {
    while (!(card_word_value & 1))
    {
    bit_position++;
    card_word_value = card_word_value / 2;
    }
    }

    // card is the card word index * card size + the bit index within the card
    card = (last_card_word - &card_table[0]) * card_word_width + bit_position;

    do
    {
    // Keep going until we get to an un-set card.
    bit_position++;
    card_word_value = card_word_value / 2;

    // If we reach the end of the card word and haven't hit a 0 yet, start going
    // card word by card word until we get to one that's not fully set (0xFFFF...)
    // or we reach card_word_end.
    if ((bit_position == card_word_width) && (last_card_word < &card_table [card_word_end]))
    {
    do
    {
    card_word_value = *(++last_card_word);
    } while ((last_card_word < &card_table [card_word_end]) &&

    #ifdef _MSC_VER
    (card_word_value == (1 << card_word_width)-1)
    #else
    // if left shift count >= width of type,
    // gcc reports error.
    (card_word_value == ~0u)
    #endif // _MSC_VER
    );
    bit_position = 0;
    }
    } while (card_word_value & 1);

    end_card = (last_card_word - &card_table [0])* card_word_width + bit_position;

    //dprintf (3, ("find_card: [%Ix, %Ix[ set", card, end_card));
    dprintf (3, ("fc: [%Ix, %Ix[", card, end_card));
    return TRUE;
    }

  • 相关阅读:
    Python-zip压缩-解压
    使用zabbix监控nginx
    原已经安装好的nginx,现在需要添加一个未被编译安装的模块:
    zabbix 邮件告警配置
    lnmp-zabbix
    Mysql新建用户和数据库并授权
    git标签管理
    Ubuntu下安装tomcat
    git分支管理
    Java拦截器
  • 原文地址:https://www.cnblogs.com/tangyanzhi1111/p/12932478.html
Copyright © 2020-2023  润新知