Beispiel #1
0
static void grow_shard(slice_shard *shard) {
  size_t capacity = shard->capacity * 2;
  size_t i;
  interned_slice_refcount **strtab;
  interned_slice_refcount *s, *next;

  GPR_TIMER_BEGIN("grow_strtab", 0);

  strtab = (interned_slice_refcount **)gpr_zalloc(
      sizeof(interned_slice_refcount *) * capacity);

  for (i = 0; i < shard->capacity; i++) {
    for (s = shard->strs[i]; s; s = next) {
      size_t idx = TABLE_IDX(s->hash, capacity);
      next = s->bucket_next;
      s->bucket_next = strtab[idx];
      strtab[idx] = s;
    }
  }

  gpr_free(shard->strs);
  shard->strs = strtab;
  shard->capacity = capacity;

  GPR_TIMER_END("grow_strtab", 0);
}
Beispiel #2
0
static void interned_slice_destroy(interned_slice_refcount *s) {
  slice_shard *shard = &g_shards[SHARD_IDX(s->hash)];
  gpr_mu_lock(&shard->mu);
  GPR_ASSERT(0 == gpr_atm_no_barrier_load(&s->refcnt));
  interned_slice_refcount **prev_next;
  interned_slice_refcount *cur;
  for (prev_next = &shard->strs[TABLE_IDX(s->hash, shard->capacity)],
      cur = *prev_next;
       cur != s; prev_next = &cur->bucket_next, cur = cur->bucket_next)
    ;
  *prev_next = cur->bucket_next;
  shard->count--;
  gpr_free(s);
  gpr_mu_unlock(&shard->mu);
}
Beispiel #3
0
static bool dirFuncValues( directive_t *dir, dir_table_enum parm )
//****************************************************************
{
    dir_operand         *dirop;
    static int_8        byte;
    static int_16       half;
    static int_32       word;
    static signed_64    quad;
    static float        flt;
    static double       dbl;
    int_32              rep;
    uint_8              prev_alignment = 0;
    int                 opnum;
    void                *target = NULL;
    owl_reloc_type      rtype = 0;
    struct { int size; void *ptr; uint_8 alignment; } data_table[] =
    {
        { 1, &byte,     0 },    // DT_VAL_INT8
        { 8, &dbl,      3 },    // DT_VAL_DOUBLE
        { 4, &flt,      2 },    // DT_VAL_FLOAT
        { 2, &half,     1 },    // DT_VAL_INT16
        { 4, &word,     2 },    // DT_VAL_INT32
        { 8, &quad,     3 },    // DT_VAL_INT64
    };
#define TABLE_IDX( x )      ( ( x ) - DT_VAL_FIRST )

#ifdef _STANDALONE_
    if( OWLTellSectionType( CurrentSection ) & OWL_SEC_ATTR_BSS ) {
        Error( INVALID_BSS_DIRECTIVE, SymName( dir->dir_sym ) );
        return( TRUE );
    }
#endif
    if( autoAlignment ) {
        prev_alignment = CurrAlignment;
        CurrAlignment = data_table[TABLE_IDX(parm)].alignment;
    }
    dirop = dir->operand_list;
    opnum = 0;
    while( dirop ) {
        rep = 1;
        switch( parm ) {
        case DT_VAL_INT8:
            assert( dirop->type == DIROP_INTEGER || dirop->type == DIROP_REP_INT );
            if( dirop->type == DIROP_INTEGER ) {
                byte = (int_8)NUMBER_INTEGER( dirop );
            } else { // repeat
                rep = REPEAT_COUNT( dirop );
                byte = (int_8)REPEAT_INTEGER( dirop );
            }
            break;
        case DT_VAL_INT64:
            assert( dirop->type == DIROP_INTEGER || dirop->type == DIROP_REP_INT );
            if( dirop->type == DIROP_INTEGER ) {
                quad.u._32[I64LO32] = NUMBER_INTEGER( dirop );
            } else { // repeat
                rep = REPEAT_COUNT( dirop );
                quad.u._32[I64LO32] = REPEAT_INTEGER( dirop );
            }
            break;
        case DT_VAL_DOUBLE:
            assert( dirop->type == DIROP_FLOATING || dirop->type == DIROP_REP_FLT );
            if( dirop->type == DIROP_FLOATING ) {
                dbl = NUMBER_FLOAT( dirop );
            } else {
                rep = REPEAT_COUNT( dirop );
                dbl = REPEAT_FLOAT( dirop );
            }
            break;
        case DT_VAL_FLOAT:
            assert( dirop->type == DIROP_FLOATING || dirop->type == DIROP_REP_FLT );
            if( dirop->type == DIROP_FLOATING ) {
                flt = (float)NUMBER_FLOAT( dirop );
            } else {
                rep = REPEAT_COUNT( dirop );
                flt = (float)REPEAT_FLOAT( dirop );
            }
            break;
        case DT_VAL_INT32:
            assert( dirop->type == DIROP_INTEGER || dirop->type == DIROP_REP_INT ||
                    dirop->type == DIROP_SYMBOL || dirop->type == DIROP_NUMLABEL_REF );
            if( dirop->type == DIROP_INTEGER ) {
                word = NUMBER_INTEGER( dirop );
            } else if( dirop->type == DIROP_REP_INT ) {
                rep = REPEAT_COUNT( dirop );
                word = REPEAT_INTEGER( dirop );
            } else {    // reloc
                word = SYMBOL_OFFSET( dirop );
                if( assignRelocType( &rtype, SYMBOL_RELOC_TYPE( dirop ), parm ) ) {
                    if( dirop->type == DIROP_SYMBOL ) {
                        target = SymName( SYMBOL_HANDLE( dirop ) );
                    } else {
                        assert( dirop->type == DIROP_NUMLABEL_REF );
                        target = &SYMBOL_LABEL_REF( dirop );
                    }
                } else {
                    Error( IMPROPER_DIROP, opnum );
                }
            }
            break;
        case DT_VAL_INT16:
            assert( dirop->type == DIROP_INTEGER || dirop->type == DIROP_REP_INT ||
                    dirop->type == DIROP_SYMBOL || dirop->type == DIROP_NUMLABEL_REF );
            if( dirop->type == DIROP_INTEGER ) {
                half = (int_16)NUMBER_INTEGER( dirop );
            } else if( dirop->type == DIROP_REP_INT ) {
                rep = REPEAT_COUNT( dirop );
                half = (int_16)REPEAT_INTEGER( dirop );
            } else {    // reloc
                half = (int_16)SYMBOL_OFFSET( dirop );
                if( assignRelocType( &rtype, SYMBOL_RELOC_TYPE( dirop ), parm ) ) {
                    if( dirop->type == DIROP_SYMBOL ) {
                        target = SymName( SYMBOL_HANDLE( dirop ) );
                    } else {
                        assert( dirop->type == DIROP_NUMLABEL_REF );
                        target = &SYMBOL_LABEL_REF( dirop );
                    }
                } else {
                    Error( IMPROPER_DIROP, opnum );
                }
            }
            break;
        default:
            Error( INTERNAL_UNKNOWN_DT_PARM, parm );
            return( FALSE );
        }
        if( target != NULL ) {
            assert( (parm == DT_VAL_INT32 || parm == DT_VAL_INT16) && rep == 1 );
#ifdef _STANDALONE_
            // align with data
            ObjEmitReloc( CurrentSection, target, rtype, ( opnum == 0 ), (dirop->type == DIROP_SYMBOL) );
#else
            // align with data
            ObjEmitReloc( target, rtype, ( opnum == 0 ), (dirop->type == DIROP_SYMBOL ) );
#endif
            target = NULL;
        }
#ifdef _STANDALONE_
        // only align for the first data operand
        ObjEmitData( CurrentSection, data_table[TABLE_IDX(parm)].ptr, data_table[TABLE_IDX(parm)].size, ( opnum == 0 ) );
#else
        // only align for the first data operand
        ObjEmitData( data_table[TABLE_IDX(parm)].ptr, data_table[TABLE_IDX(parm)].size, ( opnum == 0 ) );
#endif
        for( rep--; rep > 0; rep-- ) {
#ifdef _STANDALONE_
            OWLEmitData( CurrentSection, data_table[TABLE_IDX(parm)].ptr, data_table[TABLE_IDX(parm)].size );
#else
            ObjDirectEmitData( data_table[TABLE_IDX(parm)].ptr, data_table[TABLE_IDX(parm)].size );
#endif
#if 0
            printf( "Size=%d\n", data_table[TABLE_IDX(parm)].size );
            switch( parm ) {
            case DT_VAL_INT8:
                printf( "Out->%d\n", *(int_8 *)(data_table[TABLE_IDX(parm)].ptr) );
                break;
            case DT_VAL_DOUBLE:
                printf( "Out->%lf\n", *(double *)(data_table[TABLE_IDX(parm)].ptr) );
                break;
            case DT_VAL_FLOAT:
                printf( "Out->%f\n", *(float *)(data_table[TABLE_IDX(parm)].ptr) );
                break;
            case DT_VAL_INT16:
                printf( "Out->%d\n", *(int_16 *)(data_table[TABLE_IDX(parm)].ptr) );
                break;
            case DT_VAL_INT32:
                printf( "Out->%d\n", *(int_32 *)(data_table[TABLE_IDX(parm)].ptr) );
                break;
            case DT_VAL_INT64:
                printf( "Out->%d\n", ((signed_64 *)(data_table[TABLE_IDX(parm)].ptr))->_32[0] );
                break;
            default:
                assert( FALSE );
            }
#endif
        }
        opnum++;
        dirop = dirop->next;
    }
    if( autoAlignment ) {
        CurrAlignment = prev_alignment;
    }
    return( TRUE );
}
Beispiel #4
0
grpc_slice grpc_slice_intern(grpc_slice slice) {
  GPR_TIMER_BEGIN("grpc_slice_intern", 0);
  if (GRPC_IS_STATIC_METADATA_STRING(slice)) {
    GPR_TIMER_END("grpc_slice_intern", 0);
    return slice;
  }

  uint32_t hash = grpc_slice_hash(slice);
  for (uint32_t i = 0; i <= max_static_metadata_hash_probe; i++) {
    static_metadata_hash_ent ent =
        static_metadata_hash[(hash + i) % GPR_ARRAY_SIZE(static_metadata_hash)];
    if (ent.hash == hash && ent.idx < GRPC_STATIC_MDSTR_COUNT &&
        grpc_slice_eq(grpc_static_slice_table[ent.idx], slice)) {
      GPR_TIMER_END("grpc_slice_intern", 0);
      return grpc_static_slice_table[ent.idx];
    }
  }

  interned_slice_refcount *s;
  slice_shard *shard = &g_shards[SHARD_IDX(hash)];

  gpr_mu_lock(&shard->mu);

  /* search for an existing string */
  size_t idx = TABLE_IDX(hash, shard->capacity);
  for (s = shard->strs[idx]; s; s = s->bucket_next) {
    if (s->hash == hash && grpc_slice_eq(slice, materialize(s))) {
      if (gpr_atm_no_barrier_fetch_add(&s->refcnt, 1) == 0) {
        /* If we get here, we've added a ref to something that was about to
         * die - drop it immediately.
         * The *only* possible path here (given the shard mutex) should be to
         * drop from one ref back to zero - assert that with a CAS */
        GPR_ASSERT(gpr_atm_rel_cas(&s->refcnt, 1, 0));
        /* and treat this as if we were never here... sshhh */
      } else {
        gpr_mu_unlock(&shard->mu);
        GPR_TIMER_END("grpc_slice_intern", 0);
        return materialize(s);
      }
    }
  }

  /* not found: create a new string */
  /* string data goes after the internal_string header */
  s = (interned_slice_refcount *)gpr_malloc(sizeof(*s) +
                                            GRPC_SLICE_LENGTH(slice));
  gpr_atm_rel_store(&s->refcnt, 1);
  s->length = GRPC_SLICE_LENGTH(slice);
  s->hash = hash;
  s->base.vtable = &interned_slice_vtable;
  s->base.sub_refcount = &s->sub;
  s->sub.vtable = &interned_slice_sub_vtable;
  s->sub.sub_refcount = &s->sub;
  s->bucket_next = shard->strs[idx];
  shard->strs[idx] = s;
  memcpy(s + 1, GRPC_SLICE_START_PTR(slice), GRPC_SLICE_LENGTH(slice));

  shard->count++;

  if (shard->count > shard->capacity * 2) {
    grow_shard(shard);
  }

  gpr_mu_unlock(&shard->mu);

  GPR_TIMER_END("grpc_slice_intern", 0);
  return materialize(s);
}