void Thread::grow_execution_stack(int new_stack_size JVM_TRAPS) { ExecutionStack::Raw new_stack = Universe::new_execution_stack(new_stack_size JVM_CHECK); ExecutionStack::Raw old_stack = execution_stack(); jint old_stack_size = old_stack().length(); GUARANTEE(new_stack_size > old_stack_size, "sanity check"); GCDisabler dont_gc_for_rest_of_this_method; address old_stack_ptr = (address)stack_pointer(); jint stack_used_size; jint delta; if (JavaStackDirection < 0) { address old_stack_end = (address)old_stack().field_base(old_stack_size); address new_stack_end = (address)new_stack().field_base(new_stack_size); #ifdef UNDER_CE stack_used_size = (address)((int)old_stack_end | _system_address) - old_stack_ptr; #else stack_used_size = old_stack_end - old_stack_ptr; #endif delta = new_stack_end - old_stack_end; } else { const int offset = ExecutionStackDesc::header_size(); address old_stack_start = (address)old_stack().field_base(offset); address new_stack_start = (address)new_stack().field_base(offset); #ifdef UNDER_CE stack_used_size = old_stack_ptr - (address)((int)old_stack_start | _system_address); #else stack_used_size = old_stack_ptr - old_stack_start; #endif delta = new_stack_start - old_stack_start; } address new_stack_ptr = old_stack_ptr + delta; ((ExecutionStackDesc*)(old_stack.obj()))->relocate_internal_pointers(delta, this, true); GUARANTEE((address)stack_pointer() == new_stack_ptr, "sanity"); if (JavaStackDirection < 0) { jvm_memcpy(new_stack_ptr, old_stack_ptr , stack_used_size); } else { jvm_memcpy(new_stack_ptr - stack_used_size, old_stack_ptr - stack_used_size, stack_used_size + 4); } old_stack().clear_thread(); set_execution_stack(&new_stack); new_stack().set_thread(this); set_stack_limit(); }
size_t BufferedFile::get_bytes(address buffer, jint num, bool is_buffered) { jint total_read = 0; Buffer::Raw fb = data_buffer(); if (!is_buffered) { OsFile_seek(file_pointer(), (long)(-(count() - index())), SEEK_CUR); set_count(0); // flush buffer set_index(0); return OsFile_read(file_pointer(), buffer, 1, num); } else { while (!at_eof() && num > 0) { int num_to_read = (num > (count() - index())) ? (count() - index()) :num; // num_to_read may be zero if (num_to_read) { jvm_memcpy(buffer, fb().base_address() + (index() * sizeof (jbyte)), num_to_read); buffer += num_to_read; num -= num_to_read; set_index(index() + num_to_read); total_read += num_to_read; } if (num > 0) { refill_buffer(); } } } return total_read; }
jboolean Jvm_inflate(void *data, JvmGetByteProc getByteProc, int compLen, unsigned char** outFileH, int decompLen) { SETUP_ERROR_CHECKER_ARG; UsingFastOops fast_oops; Inflater::Fast inflater = Inflater::allocate(NULL, 0, decompLen, compLen, 0, 0 JVM_NO_CHECK); if (!CURRENT_HAS_PENDING_EXCEPTION) { unsigned char* in_data = ARRAY_BASE(inflater().in_buffer()); for (int i = 0; i < compLen; i++) { *in_data++ = getByteProc(data); } Buffer::Raw result = inflater().read_completely(JVM_SINGLE_ARG_NO_CHECK); if (result.not_null() && !CURRENT_HAS_PENDING_EXCEPTION) { jvm_memcpy(*outFileH, result().base_address(), decompLen); return KNI_TRUE; } } Thread::clear_current_pending_exception(); return KNI_FALSE; }
void ROM::initialize(const JvmPathChar* classpath) { (void)classpath; #if ENABLE_SEGMENTED_ROM_TEXT_BLOCK init_rom_text_constants(); #endif if (!_rom_has_linked_image) { GUARANTEE(UseROM == false, "sanity"); } // At this point the ObjectHeap is not yet initialized, so we can // only initialize the part that doesn't require the ObjectHeap. // We have to do this here to facilitate ROMBundle::preload() if (UseROM) { if (_rom_is_relaunchable) { if (_rom_data_block_size > 0) { jvm_memcpy(_rom_data_block, _rom_data_block_src, _rom_data_block_size); } jvm_memcpy(_rom_method_variable_parts, _rom_method_variable_parts_src, _rom_method_variable_parts_size); } } #if USE_IMAGE_PRELOADING // In SVM mode, we can load the app image into the low address of // the ObjectHeap. In MVM we don't do this because we need to handle // multiple app images. #if !ENABLE_LIB_IMAGES if (!GenerateROMImage) #endif { ROMBundle::preload(classpath); } #endif #if ENABLE_SEGMENTED_ROM_TEXT_BLOCK ROM::arrange_text_block(); #endif }
int open_socket(char* hostname, int port, int mode, jboolean nonblock) { int sock; struct sockaddr_in destination_sin; struct hostent* phostent = NULL; init_sockets(); // Create a TCP/IP socket if ((sock = jvm_socket(AF_INET, SOCK_STREAM, 0)) < 0) { return -1; } // Retrieve the host information corresponding to the host name. if ((phostent = (struct hostent*)jvm_gethostbyname(hostname)) == NULL) { jvm_shutdown(sock, 2); // IMPL_NOTE: Linux: still need to close the file descriptor! return -1; } // Assign the socket IP address. destination_sin.sin_family = AF_INET; destination_sin.sin_port = jvm_htons(port); jvm_memcpy((char *)&(destination_sin.sin_addr), phostent->h_addr, phostent->h_length); // Establish a connection to the server. if (jvm_connect(sock, (struct sockaddr*)&destination_sin, sizeof(destination_sin)) < 0) { jvm_shutdown(sock, 2); return -1; } if (nonblock == KNI_TRUE) { u_long flag = 1; #ifdef USE_UNISTD_SOCKETS jvm_fcntl(sock, F_SETFL, O_NONBLOCK); #else if (ioctlsocket(sock, FIONBIO, &flag) < 0) { jvm_shutdown(sock, 2); return -1; } #endif } return sock; }
void PacketStream::read_bytes(void *dest, int size) { if (_error) { return; } if (dest) { if (size > (_input_data.length() - _output_index)) { set_error(JDWP_Error_ILLEGAL_ARGUMENT); return; } jvm_memcpy(dest, current_output_addr(), size); _output_index += size; } }
ReturnOop SymbolTable::slashified_symbol_for(utf8 s, int len JVM_TRAPS) { UsingFastOops fast_oops; TypeArray::Fast byte_array = Universe::new_byte_array(len JVM_CHECK_0); utf8 p = (utf8)byte_array().base_address(); jvm_memcpy(p, s, len); for (int i = 0; i < len; i++) { if (p[i] == '/') { // This makes external class names which already contain '/' instead // of '.' fail resolution p[i] = '.'; } else if (p[i] == '.') { p[i] = '/'; } } return symbol_for(&byte_array JVM_NO_CHECK_AT_BOTTOM_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(); } }
KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_cldc_io_j2me_socket_Protocol_open0() { init_sockets(); SocketOpenParameter *p = (SocketOpenParameter*) SNI_GetReentryData(NULL); if (p == NULL) { p = (SocketOpenParameter*) SNI_AllocateReentryData(sizeof(*p)); p->fd = -1; struct hostent *phostent; KNI_StartHandles(1); KNI_DeclareHandle(hostname_object); KNI_GetParameterAsObject(1, hostname_object); // hostname is always NUL terminated. See socket/Protocol.java for detail. char *hostname = (char*) SNI_GetRawArrayPointer(hostname_object); phostent = (struct hostent*)jvm_gethostbyname(hostname); KNI_EndHandles(); if (phostent == NULL) { KNI_ReturnInt(-1); } struct sockaddr_in destination_sin; destination_sin.sin_family = AF_INET; int port = KNI_GetParameterAsInt(2); destination_sin.sin_port = jvm_htons(port); jvm_memcpy((char *) &destination_sin.sin_addr, phostent->h_addr, phostent->h_length); p->fd = jvm_socket(AF_INET, SOCK_STREAM, 0); if (p->fd < 0) { KNI_ReturnInt(-1); } if (!set_blocking_flags(&p->fd, /*is_blocking*/ KNI_FALSE)) { KNI_ReturnInt(-1); } if (jvm_connect(p->fd, (struct sockaddr *) &destination_sin, sizeof(destination_sin)) < 0) { int err_code = GET_LAST_ERROR(); if (err_code == EINPROGRESS) { // When the socket is ready for connect, it becomes *writable* // (according to BSD socket spec of select()) p->check_flags = CHECK_WRITE | CHECK_EXCEPTION; SNI_BlockThread(); } else { jvm_shutdown(p->fd, 2); closesocket(p->fd); p->fd = -1; } } KNI_ReturnInt(p->fd); } else { // When we come to here, a CheckEvent() call has reported one of the // following: // [1] connect() has succeeded. In this case we return the socket fd. // [2] connect() has failed. In this case CheckEvent has already closed // the socket and set p->fd to -1. So we'd be returning -1. KNI_ReturnInt(p->fd); } }
// Create or retrieve a JarFileParser for the given JAR file. // As a side effect, it might invalidate any previously obtained // JarFileParser objects by closing their OsFile_handles. ReturnOop JarFileParser::get(const JvmPathChar* jar_file_name1, TypeArray * jar_file_name2, bool enable_entry_cache JVM_TRAPS) { GUARANTEE((jar_file_name1 != NULL && jar_file_name2 == NULL) || (jar_file_name1 == NULL && jar_file_name2 != NULL), "sanity"); UsingFastOops fast_oops; JarFileParser::Fast parser = get_parser_from_cache(jar_file_name1, jar_file_name2); if (parser.not_null()) { return parser; } if (jar_file_name1 && !OsFile_exists(jar_file_name1)) { return NULL; } if (jar_file_name2 && !OsFile_exists((JvmPathChar *)jar_file_name2->byte_base_address())) { return NULL; } parser = Universe::new_mixed_oop(MixedOopDesc::Type_JarFileParser, JarFileParser::allocation_size(), JarFileParser::pointer_count() JVM_CHECK_0); TypeArray::Fast stored_name; if (jar_file_name1 != NULL) { size_t name_bytes = (fn_strlen(jar_file_name1)+1) * sizeof(JvmPathChar); stored_name = Universe::new_byte_array_raw(name_bytes JVM_CHECK_0); JvmPathChar *data = (JvmPathChar *)stored_name().byte_base_address(); jvm_memcpy(data, jar_file_name1, name_bytes); // copy trailing NUL as well. } else { stored_name = jar_file_name2->obj(); } BufferedFile::Fast bf = BufferedFile::allocate(JVM_SINGLE_ARG_CHECK_0); FileDescriptor::Fast desc = FileDescriptor::allocate(JVM_SINGLE_ARG_CHECK_0); OsFile_Handle fh = NULL; for (int pass=0; pass<2; pass++) { if (jar_file_name1) { fh = OsFile_open(jar_file_name1, "rb"); } else { fh = OsFile_open((JvmPathChar *)jar_file_name2->byte_base_address(), "rb"); } if (fh != NULL) { break; } if (pass == 1 && fh == NULL) { // The system is running low on OsFile_Handles. Make sure we flush // the cache, and free all currently cached OsFile_Handles that belong // to other JAR files. flush_caches(); } } if (fh == NULL) { return NULL; } desc().set_handle(fh); bf().set_file_pointer(fh); bf().set_file_size(fh == NULL ? 0 : OsFile_length(fh)); parser().set_file_descriptor(&desc); parser().set_enable_entry_cache(enable_entry_cache); parser().set_pathname(&stored_name); parser().set_buffered_file(&bf); parser().set_timestamp(++_timestamp); if (!parser().find_end_of_central_header()) { // The jar file is corrupted. Stop parsing it. return NULL; } parser().save_parser_in_cache(JVM_SINGLE_ARG_MUST_SUCCEED); return parser; }
jboolean LocationModifier::set_method_opcode(Bytecodes::Code new_opcode, bool is_setting) { UsingFastOops fast_oops; Method::Fast m = method(); jlong offs = offset(); Bytecodes::Code opcode; SETUP_ERROR_CHECKER_ARG; if (m.is_null()) { // If we are clearing a breakpoint and this was a <clinit> method // and we removed <clinit> after the class was intialized then we // return since there's nothing to do return false; } #ifdef AZZERT /* Determine if this is a legal offset * into the bytecode for this method */ if (!JavaDebugger::is_legal_offset(&m, offs)) { return false; } #endif if (offs >= m().code_size()) { // quick check for out of bounds, could happen if method was // converted to fast_accessor return false; } if (ROM::system_text_contains(m.obj())) { // This method is in ROM so we need to copy it out so that // we can modify breakpoints. UsingFastOops fast_oops_2; Method::Fast dm = get_dup_rom_method(&m); if (is_setting) { if (dm.is_null()) { AccessFlags af = m().access_flags(); dm = Universe::new_method(m().code_size(), af JVM_CHECK_0); jvm_memcpy((char *)dm.obj() + dm().access_flags_offset(), (char *) m.obj() + m().access_flags_offset(), Method::base_offset() + m().code_size() - m().access_flags_offset()); // ROM method constants pointer points into ROM text if we // merged pools ConstantPool::Raw cp = m().constants(); dm().set_constants(&cp); if (!m().has_no_stackmaps()) { Oop::Raw stackmaps = m().stackmaps(); dm().set_stackmaps(&stackmaps); } if (!m().has_no_exception_table()) { Oop::Raw exception_table = m().exception_table(); dm().set_exception_table(&exception_table); } #if ENABLE_REFLECTION Oop::Raw thrown_exceptions = m().thrown_exceptions(); dm().set_thrown_exceptions(&thrown_exceptions); #endif set_rom_debug_method(&dm); } opcode = m().bytecode_at_raw((int)offs); dm().bytecode_at_put_raw((int)offs, new_opcode); m().set_execution_entry((address)shared_invoke_debug); dm().set_execution_entry((address)shared_invoke_debug); } else { // We are clearing a breakpoint that was set in ROM (actually in // a copy of the ROM method) dm = rom_debug_method(); GUARANTEE(!dm.is_null(), "Clearing ROM breakpoint, but method is null!"); opcode = dm().bytecode_at_raw((int)offs); // install new opcode into bytecode stream dm().bytecode_at_put_raw((int)offs, new_opcode); } } else { opcode = m().bytecode_at_raw((int)offs); // install new opcode into bytecode stream m().bytecode_at_put_raw((int)offs, new_opcode); } if (is_setting) { set_save_opcode(opcode); } return (true); }