void set_local_variable_table(OopDesc *value) { obj_at_put(VAR_TABLE_INDEX, value); }
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); }