You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by mc...@apache.org on 2008/03/26 07:22:17 UTC
svn commit: r641169 - in /harmony/enhanced/drlvm/trunk/vm/vmcore:
include/environment.h include/jarfile_support.h
src/class_support/classloader.cpp src/init/vm_init.cpp
src/util/jarfile_support.cpp
Author: mcfirst
Date: Tue Mar 25 23:22:16 2008
New Revision: 641169
URL: http://svn.apache.org/viewvc?rev=641169&view=rev
Log:
Applying patch from HARMONY-5281 [drlvm][startup][performance][classloader] mapping bootstrap jars directly into memory. The option vm.map_bootstrap_jars is turned off by default.
Modified:
harmony/enhanced/drlvm/trunk/vm/vmcore/include/environment.h
harmony/enhanced/drlvm/trunk/vm/vmcore/include/jarfile_support.h
harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_init.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/jarfile_support.cpp
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/environment.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/environment.h?rev=641169&r1=641168&r2=641169&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/environment.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/environment.h Tue Mar 25 23:22:16 2008
@@ -94,6 +94,12 @@
bool use_common_jar_cache;
/**
+ * If set to true, jar files are mapped into memory instead of reading
+ * them from disk.
+ */
+ bool map_bootsrtap_jars;
+
+ /**
* If set to true by the <code>-compact_fields</code> command-line option,
* the VM will not pad out fields of less than 32 bits to four bytes.
* However, fields will still be aligned to a natural boundary,
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/jarfile_support.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jarfile_support.h?rev=641169&r1=641168&r2=641169&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/jarfile_support.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/jarfile_support.h Tue Mar 25 23:22:16 2008
@@ -33,6 +33,7 @@
#else
#include <io.h>
#endif
+#include "apr_mmap.h"
#include "properties.h"
#include "manifest.h"
@@ -209,31 +210,39 @@
JarEntryCache* m_entries;
bool m_ownCache;
Manifest* m_manifest;
- tl::MemoryPool pool;
+ tl::MemoryPool m_pool;
+ // handle of the jar file
+ int m_file_handle;
+ // associated lock
+ Lock_Manager m_lock;
+ // should jar support use mmap instead of open/read
+ bool m_use_mmap;
+ // apr pool to use with mmap
+ apr_pool_t* m_mappool;
+ // apr file object for mapping
+ apr_file_t* m_jarfile;
+ // memory location for jar
+ apr_mmap_t* m_mmap;
// list of the jar files
static std::vector<JarFile*> m_jars;
public:
JarFile(JarEntryCache* jec = NULL)
- : m_name(NULL), m_entries(jec), m_ownCache(jec == NULL), m_manifest(NULL), jfh(0) {}
- JarFile( const JarFile& jf ) : jfh(0) {
- m_name = jf.m_name;
- m_entries = jf.m_entries;
- m_manifest = new Manifest(jf.m_manifest);
- }
+ : m_name(NULL), m_entries(jec), m_ownCache(jec == NULL), m_manifest(NULL), m_file_handle(0),
+ m_use_mmap(false), m_mmap(NULL) {}
~JarFile() {
if(m_ownCache)
m_entries->~JarEntryCache();
m_ownCache = false;
m_entries = NULL;
- if (jfh != 0) close(jfh);
- jfh = 0;
+ if (m_file_handle != 0) close(m_file_handle);
+ m_file_handle = 0;
if( m_manifest ) delete m_manifest;
m_manifest = NULL;
}
// parses JAR file and stores its structure inside
- bool Parse( const char* filename );
+ bool Parse( const char* filename, bool do_map );
// returns entry cache (either shared or owned)
JarEntryCache* GetCache() { return m_entries; }
// returns if this JarFile owns entry cache it holds
@@ -241,6 +250,7 @@
const JarEntry* Lookup( const char* je_name ) const {
return m_entries->Lookup(je_name);
}
+ bool ReadEntry(unsigned char* buf, long entry_offset, int entry_length);
// returns manifest from parsed jar archive
Manifest* GetManifest() { return m_manifest; }
// returns JAR file name
@@ -250,10 +260,6 @@
static JarFile* GetJar(int idx) {
return m_jars[idx];
}
-
- // handle of the jar file
- int jfh;
- Lock_Manager lock;
}; // class JarFile
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp?rev=641169&r1=641168&r2=641169&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp Tue Mar 25 23:22:16 2008
@@ -1182,7 +1182,8 @@
void* mem_JarFile = apr_palloc(pool, sizeof(JarFile));
element->m_jar = new (mem_JarFile) JarFile(jec);
- if(element->m_jar && element->m_jar->Parse(new_path->bytes)) {
+ if(element->m_jar && element->m_jar->Parse(new_path->bytes, m_env->map_bootsrtap_jars))
+ {
TRACE2("classloader.jar", "opened archive: " << new_path );
}
}
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_init.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_init.cpp?rev=641169&r1=641168&r2=641169&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_init.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_init.cpp Tue Mar 25 23:22:16 2008
@@ -842,6 +842,7 @@
vm_env->sort_fields = get_boolean_property("vm.sort_fields", vm_env->sort_fields, VM_PROPERTIES);
vm_env->compact_fields = get_boolean_property("vm.compact_fields", vm_env->compact_fields, VM_PROPERTIES);
vm_env->use_common_jar_cache = get_boolean_property("vm.common_jar_cache", TRUE, VM_PROPERTIES);
+ vm_env->map_bootsrtap_jars = get_boolean_property("vm.map_bootstrap_jars", FALSE, VM_PROPERTIES);
vm_env->init_pools();
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/jarfile_support.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/jarfile_support.cpp?rev=641169&r1=641168&r2=641169&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/jarfile_support.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/jarfile_support.cpp Tue Mar 25 23:22:16 2008
@@ -54,19 +54,11 @@
{
// length of content should be enough for storing m_size_uncompressed bytes
JarFile* jf = JarFile::GetJar(m_jarFileIdx);
- int inFile = jf->jfh;
- // gregory - It is necessary to lock per jar file because the file
- // handle is global to all threads, and file operations like seek,
- // read, etc may be confused when many threads operate on the same
- // jar file
- LMAutoUnlock lock(&jf->lock);
-
- if( lseek( inFile, m_contentOffset, SEEK_SET ) == -1 ) return false;
switch( m_method )
{
case JAR_FILE_STORED:
- return ( read( inFile, content, m_sizeCompressed ) == m_sizeCompressed );
+ return jf->ReadEntry(content, m_contentOffset, m_sizeCompressed);
case JAR_FILE_SHRUNK:
printf( "Found SHRUNK content. No support as of yet.\n" );
return false;
@@ -96,7 +88,7 @@
{
unsigned char* data = (unsigned char*)STD_MALLOC(m_sizeCompressed + 1);
// FIXME: check that memory was allocated
- if( read( inFile, data, m_sizeCompressed ) < m_sizeCompressed ) {
+ if(!jf->ReadEntry(data, m_contentOffset, m_sizeCompressed)) {
STD_FREE(data);
return false;
}
@@ -121,6 +113,8 @@
infRes = inflate( &inf, Z_FINISH );
STD_FREE(data);
if( infRes != Z_STREAM_END ) {
+ // FIXME: this is broken stream actually
+ // and breaking will result in "Invalid class magic" later on
break;
}
infRes = inflateEnd( &inf );
@@ -145,31 +139,60 @@
#pragma warning( disable: 4786 ) // identifier was truncated to 255 characters in the browser information
#endif
-bool JarFile::Parse( const char* fileName )
+bool JarFile::Parse( const char* fileName, bool do_map )
{
- int flags = O_RDONLY;
-#ifndef PLATFORM_POSIX
- flags |= O_BINARY;
-#endif
- int fp = open( fileName, flags, 0 );
- jfh = fp;
- if( fp == -1 ) return false;
+ int fp;
+ long off;
+ unsigned char* buf;
+ unsigned long fsize = 0;
+ m_use_mmap = do_map;
m_name = fileName;
- struct stat fs;
- if(stat(fileName, &fs) == -1) return false;
- unsigned long fsize = fs.st_size;
+ if(!m_use_mmap) {
+ int flags = O_RDONLY;
+#ifndef PLATFORM_POSIX
+ flags |= O_BINARY;
+#endif
+ fp = open( fileName, flags, 0 );
+ if( fp == -1 ) return false;
+
+ m_file_handle = fp;
- m_jars.push_back(this);
+ struct stat fs;
+ if(stat(fileName, &fs) == -1) return false;
+ fsize = fs.st_size;
+
+ int cd_size = fsize < 67000 ? fsize : 67000;
+ lseek(fp, -cd_size, SEEK_END);
+ buf = (unsigned char*)STD_ALLOCA(cd_size);
+ off = read(fp, buf, cd_size) - 22; // 22 - EOD size
+ } else {
+ apr_pool_create(&m_mappool, NULL);
+
+ apr_status_t status =
+ apr_file_open(&m_jarfile, fileName, APR_READ, APR_OS_DEFAULT, m_mappool);
+ assert(!status);
+
+ apr_off_t _fsize = 0;
+ status = apr_file_seek(m_jarfile, APR_END, &_fsize);
+ assert(!status);
+ fsize = (unsigned long)_fsize;
+
+ status = apr_mmap_create(&m_mmap, m_jarfile, 0, (apr_size_t)fsize,
+ APR_MMAP_READ, m_mappool);
+ assert(!status);
+
+ int cd_size = fsize < 67000 ? fsize : 67000;
+ off = cd_size - 22;
+ buf = (unsigned char*)m_mmap->mm + fsize - cd_size;
+ }
- int cd_size = fsize < 67000 ? fsize : 67000;
- lseek(fp, -cd_size, SEEK_END);
- unsigned char *buf = (unsigned char *)STD_ALLOCA(cd_size);
- long off = read(fp, buf, cd_size) - 22; // 22 - EOD size
long offsetCD; // start of the Central Dir
int number; // number of entries
+ m_jars.push_back(this);
+
JarEntry je;
je.m_jarFileIdx = (int)(m_jars.size() - 1);
@@ -186,18 +209,19 @@
return false;
}
- m_manifest = new Manifest();
- if(!m_manifest) return false;
-
if(m_ownCache) {
- void* jec_mem = pool.alloc(sizeof(JarEntryCache));
+ void* jec_mem = m_pool.alloc(sizeof(JarEntryCache));
m_entries = new (jec_mem) JarEntryCache();
}
- lseek(fp, offsetCD, SEEK_SET);
+ if(!m_use_mmap) {
+ lseek(fp, offsetCD, SEEK_SET);
- buf = (unsigned char *)STD_MALLOC(fsize - offsetCD);
- fsize = read(fp, buf, fsize - offsetCD);
+ buf = (unsigned char *)STD_MALLOC(fsize - offsetCD);
+ fsize = read(fp, buf, fsize - offsetCD);
+ } else {
+ buf = (unsigned char*)m_mmap->mm + offsetCD;
+ }
off = 0;
for (int i = 0; i < number; i++){
@@ -205,14 +229,15 @@
return false;
je.ConstructFixed(buf + off);
- je.m_fileName = (char *)pool.alloc(je.m_nameLength + 1);
+ je.m_fileName = (char *)m_pool.alloc(je.m_nameLength + 1);
strncpy(je.m_fileName, (const char *)buf + off + JAR_DIRECTORYENTRY_LEN, je.m_nameLength );
je.m_fileName[je.m_nameLength] = '\0';
je.m_contentOffset = je.m_relOffset + JarEntry::sizeFixed + je.m_nameLength + je.m_extraLength;
if(!strcmp(je.m_fileName, "META-INF/MANIFEST.MF")) {
// parse manifest
- if(!m_manifest->Parse(&je)) return false;
- if(!(*m_manifest)) {
+ m_manifest = new Manifest();
+ if(!m_manifest) return false;
+ if(!m_manifest->Parse(&je) || !(*m_manifest)) {
delete m_manifest;
return false;
}
@@ -225,7 +250,29 @@
}
off += JAR_DIRECTORYENTRY_LEN + je.m_nameLength + je.m_extraLength;
}
- STD_FREE(buf);
+ if(!m_use_mmap) {
+ STD_FREE(buf);
+ }
+
+ return true;
+}
+
+
+bool JarFile::ReadEntry(unsigned char* buf, long entry_offset, int entry_length)
+{
+ if(!m_use_mmap) {
+ // gregory - It is necessary to lock per jar file because the file
+ // handle is global to all threads, and file operations like seek,
+ // read, etc may be confused when many threads operate on the same
+ // jar file
+ LMAutoUnlock llock(&m_lock);
+
+ if(lseek(m_file_handle, entry_offset, SEEK_SET) == -1) return false;
+
+ if(read(m_file_handle, buf, entry_length) < entry_length) return false;
+ } else {
+ memcpy(buf, (char*)m_mmap->mm + entry_offset, entry_length*sizeof(char));
+ }
return true;
}