Пример #1
0
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();
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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
}
Пример #5
0
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;
}
Пример #6
0
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;
  }
}
Пример #7
0
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);
}
Пример #8
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();
  }
}
Пример #9
0
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);
  }
}
Пример #10
0
// 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;
}
Пример #11
0
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);
}