// Bytecode dispatch table for ARM Interpreter/Thumb Compiler void GPTableGenerator::generate_thumb_bytecode_dispatch_table() { int i; define_long(0); // 256 or 263 define_long(0); // 255 or 262 if (ENABLE_DISPATCH_TABLE_PADDING) { SHOULD_NOT_REACH_HERE(); // This is a bit bogus -- padded dispatch tables must be ascending, // so it won't work with Thumb compiler! define_long("bytecode_dispatch_0x105"); define_long("bytecode_dispatch_0x104"); define_long("bytecode_dispatch_0x103"); define_long("bytecode_dispatch_0x102"); define_long("bytecode_dispatch_0x101"); define_long("bytecode_dispatch_0x100"); define_long("bytecode_dispatch_0x0FF"); define_long("bytecode_dispatch_0x0FE"); } for (i = 253; i > 0; i--) { Bytecodes::Code bc = (Bytecodes::Code) i; if (Bytecodes::is_defined(bc) && !GenerateGPTableOnly) { char buffer[256]; if (GenerateGNUCode) { jvm_sprintf(buffer, "bc_impl_%-30s /* 0x%x */", Bytecodes::name(bc), (int)bc); } else { jvm_sprintf(buffer, "bc_impl_%-30s ; 0x%x", Bytecodes::name(bc), \ (int)bc); } define_long(buffer); } else { define_long(0); } } bind("gp_base_label"); set_current_commented_offset(0); set_use_offset_comments(true); if (!GenerateGPTableOnly) { // Define nop at offset 0 from base_label // the rest would be at -ve offset char buffer[256]; if (GenerateGNUCode) { jvm_sprintf(buffer, "bc_impl_%-30s /* 0x%x */", Bytecodes::name((Bytecodes::Code)0), 0); } else { jvm_sprintf(buffer, "bc_impl_%-30s ; 0x%x", Bytecodes::name((Bytecodes::Code)0), 0); } define_long(buffer); } else { define_long(0); } }
void ClassInfo::iterate_tables(OopROMVisitor* visitor) { int index = 0; if (vtable_length() > 0) { visitor->do_comment("Virtual dispatch table"); for (index = 0; index < vtable_length(); index++) { IndexableField field(index, true); visitor->do_oop(&field, vtable_offset_from_index(index), true); } } if (itable_length() > 0){ visitor->do_comment("Interface dispatch table"); for (index = 0; index < itable_length(); index++) { { InstanceClass ic = itable_interface_at(index); Symbol name = ic.name(); char buffer[1024]; jvm_sprintf(buffer, "interface klass_index "); name.string_copy(buffer + jvm_strlen(buffer), sizeof(buffer) - jvm_strlen(buffer)); NamedField field(buffer, true); visitor->do_int(&field, itable_offset_from_index(index), true); } { NamedField field("offset", true); visitor->do_int(&field, itable_offset_from_index(index) + sizeof(jint), true); } } for (index = 0; index < itable_length(); index++) { int offset = itable_offset_at(index); // Some ROM's interfaces that implement other interfaces set // offset=0, since this information is actually needed by // anyone. if (offset > 0) { InstanceClass ic = itable_interface_at(index); Symbol name = ic.name(); ObjArray methods = ic.methods(); const int buffer_size = 256; char buffer[256]; jvm_sprintf(buffer, "Table for interface #%d: ", index); name.string_copy(buffer + jvm_strlen(buffer), buffer_size- jvm_strlen(buffer)); visitor->do_comment(buffer); for (int i = 0; i < methods.length(); i ++) { IndexableField field(i, true); visitor->do_oop(&field, offset + i * sizeof(jobject), true); } } } } }
void SourceAssembler::bind_rom_linkable(const char *name, bool generate_fixed) { char fixed_name[256]; jvm_sprintf(fixed_name, "fixed_%s", name); Label L(name); Label L_fixed(fixed_name); if (generate_fixed) { bind_global(L_fixed); nop(); } bind_global(L); }
// Bytecode dispatch table for ARM Interpreter/Compiler void GPTableGenerator::generate_arm_bytecode_dispatch_table() { int i; bind("gp_base_label"); set_current_commented_offset(0); set_use_offset_comments(true); for (i = 0; i <= 253; i++) { Bytecodes::Code bc = (Bytecodes::Code) i; if (Bytecodes::is_defined(bc) && !GenerateGPTableOnly) { char buffer[256]; if (GenerateGNUCode) { jvm_sprintf(buffer, "bc_impl_%-30s /* 0x%x */", Bytecodes::name(bc), (int)bc); } else { jvm_sprintf(buffer, "bc_impl_%-30s ; 0x%x", Bytecodes::name(bc), (int)bc); } define_long(buffer); } else { eol_comment("undefined bytecode 0x%x", bc); define_long(0); } } if (ENABLE_DISPATCH_TABLE_PADDING) { define_long("bytecode_dispatch_0x0FE"); define_long("bytecode_dispatch_0x0FF"); define_long("bytecode_dispatch_0x100"); define_long("bytecode_dispatch_0x101"); define_long("bytecode_dispatch_0x102"); define_long("bytecode_dispatch_0x103"); define_long("bytecode_dispatch_0x104"); define_long("bytecode_dispatch_0x105"); } define_long(0); // 255 or 262 define_long(0); // 256 or 263 }
void SourceAssembler::add_using_gp(Register reg, const char *name, Condition cond) { int offset = find_gp_offset(name); if (is_rotated_imm(offset)) { eol_comment(name); add(reg, gp, imm(offset), cond); } else { char buff[128]; jvm_sprintf(buff, "slow add_gp_imm %s %d", name, offset); eol_comment(buff); offset -= 1024; GUARANTEE(is_rotated_imm(1024), "sanity"); GUARANTEE(is_rotated_imm(offset), "sanity"); add(reg, gp, imm(1024), cond); add(reg, reg, imm(offset), cond); } }
void report_error(bool is_vm_internal_error, const char* file_name, int line_no, const char* title, const char* format, ...) { static int error_level = 1; // Handle the recursive case switch(error_level++) { case 1: // first time, do nothing break; case 2: // second time print recursive problem tty->print_cr("[error occurred during error reporting]"); return; default: // otherwise just say NO. JVM::exit(-1); } // Compute the message char message[2*1024]; va_list ap; va_start(ap, format); jvm_vsprintf(message, format, ap); va_end(ap); if (is_vm_internal_error) { // Print error has happen tty->cr(); tty->print_cr("#"); tty->print_cr("# VM Error, %s", title); tty->print_cr("#"); char loc_buf[256]; if (file_name != NULL) { int len = jvm_strlen(file_name); jvm_strncpy(loc_buf, file_name, 256); if (len + 10 < 256) { jvm_sprintf(loc_buf + len, ", %d", line_no); } } else { jvm_strcpy(loc_buf, "<unknown>"); } tty->print_cr("# Error ID: %s", loc_buf); tty->print_cr("#"); } { char* begin = message; // print line by line for (;;) { char* end = (char *) jvm_strchr(begin, '\n'); if (!end) { break; } *end = '\0'; tty->print_raw("# "); tty->print_raw(begin); *end = '\n'; begin = end + 1; } // print last line if (*begin) { tty->print_raw("# "); tty->print_raw(begin); tty->cr(); } // print end mark tty->print_cr("#"); } error_level--; }
void GPTableGenerator::generate_constants_table() { int i; bind("gp_constants"); static const GPTemplate gp_templates[] = { GP_SYMBOLS_DO(DEFINE_GP_POINTER, DEFINE_GP_VALUE) {NULL, 0, 0, 0} }; for (const GPTemplate* tmpl = gp_templates; tmpl->name; tmpl++) { if (tmpl->is_pointer) { char buff[120]; jvm_sprintf(buff, "gp_%s_ptr", tmpl->name); bind(buff); Label L(tmpl->name); if (!tmpl->is_asm) { import(L); } define_long(L); } else { if (jvm_strcmp(tmpl->name, "current_thread") == 0) { bind("jvm_fast_globals"); } char buff[120]; jvm_sprintf(buff, "_%s", tmpl->name); bind(buff); if (jvm_strcmp(tmpl->name, "bit_selector") == 0) { // IMPL_NOTE: create a common framework to define initial values define_long(0x80808080); } else { define_zeros(tmpl->size); } } } if (!GenerateGPTableOnly) { // Some constants to check we've linked with the right ROM Label L1(XSTR(_ROM_LINKCHECK_HLE)); import(L1); define_long(L1); Label L2(XSTR(_ROM_LINKCHECK_MFFD)); import(L2); define_long(L2); Label L3(XSTR(_ROM_LINKCHECK_MFFL)); import(L3); define_long(L3); } if (ENABLE_THUMB_GP_TABLE && GenerateGPTableOnly) { // These symbols are necessary to link romgen. // We define a long for each entry, since they // should be bound to different addresses. bind("jvm_ladd"); define_long(0); bind("jvm_lsub"); define_long(0); bind("jvm_land"); define_long(0); bind("jvm_lor"); define_long(0); bind("jvm_lxor"); define_long(0); bind("jvm_lcmp"); define_long(0); bind("jvm_lmin"); define_long(0); bind("jvm_lmax"); define_long(0); bind("jvm_lmul"); define_long(0); bind("jvm_lshl"); define_long(0); bind("jvm_lshr"); define_long(0); bind("jvm_lushr"); define_long(0); } bind("gp_constants_end"); }