void set_local_variable_table(OopDesc *value) {
   obj_at_put(VAR_TABLE_INDEX, value);
 }
Exemple #2
0
ReturnOop
SymbolTable::symbol_for(TypeArray *byte_array, utf8 s, int len,
                        bool check_only JVM_TRAPS) {
  if (byte_array == NULL) {
    // If the source of the new symbol lives in the heap, you must
    // GC-protect it by passing the source in a byte_array
    GUARANTEE(!ObjectHeap::contains((OopDesc*)s), "must not be in heap");
  }

  if (unsigned(len) > 0xfff0) {
    // Symbol's string length is a unsigned 16-bit number
    Throw::out_of_memory_error(JVM_SINGLE_ARG_THROW_0);
  }

  const juint hash_value = hash(s, len);

  if (UseROM) {
    // The ROM symbol table's layout is different than that of the
    // symbol table in heap. The main reason is to avoids holes in 
    // the table.
    //

    // **************************************************************
    // WARNING: the value of ROM::symbol_table_num_buckets() is 1 off
    // what you would think. Read the following carefully.
    // **************************************************************
    //
    // Layout of the ROM symbol table with <n> buckets:
    //
    // (a) The first <n> elements are pointers to the start of the
    //     <n> buckets. Note that element <n> also marks the exclusive 
    //     end of the <n-1> bucket.
    // (b) One additional element is written at to mark the exclusive
    //     end of the very last bucket.
    // (c) If RewriteROMConstantPool is disabled, the contents of
    //     bucket #0 starts here, followed by the contents of bucket #1,
    //     and so forth.
    //
    // For example, say we have two buckets; bucket #0 contains "foo";
    // bucket #1 contains "bar" and "blah":
    //
    // symbol_table_size = 2;
    // symbol_table[] = {
    //     &symbol_table[3];          // (a) start of bucket#0
    //     &symbol_table[4];          // (a) end of bucket#0/start of bucket#1
    //     &symbol_table[6];          // (b) end of bucket#1
    //     pointer to Symbol "foo";   // (c) item in bucket#0
    //     pointer to Symbol "bar";   // (c) item in bucket#1
    //     pointer to Symbol "blah";  // (c) item in bucket#1
    // };
    //
    // Note that if RewriteROMConstantPool is enabled (the default),
    // part (c) is actually stored inside the merged constant pool;
    // parts (a) and (b) are written with special macros to point to
    // the merged constant pool instead.

    ReturnOop old_sym = ROM::symbol_for(s, hash_value, len);
    if( old_sym ) {
      return old_sym;
    }
  }

  const juint mask = juint(length() - 1);
  juint index = hash_value & mask;

  const juint start = index;

  SymbolDesc**base = (SymbolDesc**)base_address();
  SymbolDesc* old;

  if (0 < len && len <= 6) {
    // Quicker search. This happens very frequently if a MIDlet is
    // obfuscated -- many variables will have name length <= 6
    //
    // Note: this requires that the unused space in the SymbolDesc be filled
    // with zeros.
    union {
      jushort shorts[4];
      juint   ints[2];
    } blob;
    blob.ints[0] = 0;
    blob.ints[1] = 0;
    blob.shorts[0] = (jushort)len;
    jvm_memcpy(&blob.shorts[1], s, len);

    const juint blob0 = blob.ints[0];
    if( len <= 2 ) {
      do {
        old = base[index];
        if( old == NULL ) break;
        const juint *body = ((const juint*)old) + sizeof(OopDesc)/BytesPerWord;
        if (blob0 == body[0]) {
          return (ReturnOop)old;
        }
        index ++;
        index &= mask;
        // Do not rewrite as  while( (index = (++index & mask)) != start );
        // ADS compiler generates incorrect code.
      } while( index != start );
    } else {
      const juint blob1 = blob.ints[1];
      do {
        old = base[index];
        if( old == NULL ) break;
        const juint *body = ((const juint*)old) + sizeof(OopDesc)/BytesPerWord;
        if( blob0 == body[0] && blob1 == body[1] ) {
          return (ReturnOop)old;
        }
        index ++;
        index &= mask;
        // Do not rewrite as  while( (index = (++index & mask)) != start );
        // ADS compiler generates incorrect code.
      } while( index != start );
    }
  } else {
    do {
      old = base[index];
      if( old == NULL ) break;
      if( old->matches(s, len)) {
        return (ReturnOop)old;
      }
      index ++;
      index &= mask;
      // Do not rewrite as  while( (index = (++index & mask)) != start );
      // ADS compiler generates incorrect code.
    } while( index != start );
  }

  if (check_only) {
    // The specified symbol is not found
    return NULL;
  } else {
    if( old ) {
      // We'd come to here if we're really out of memory
      Throw::out_of_memory_error(JVM_SINGLE_ARG_THROW_0);
    }

    // Create a new Symbol of the specified value
    UsingFastOops fast_oops;
    Symbol::Fast new_symbol = Universe::new_symbol(byte_array, s, len 
                                                   JVM_CHECK_0);
    obj_at_put(index, &new_symbol);

    int new_count = Task::current()->incr_symbol_table_count();
    if (new_count > desired_max_symbol_count()) {
      grow_and_replace_symbol_table();
    }
    return new_symbol.obj();
  }
}
 void set_line_number_table(OopDesc *value) {
   obj_at_put(LINE_TABLE_INDEX, value);
 }