Introducing MemoryMappedExternalResource for creating an external
resource from a memory mapped file for creating strings. Patch by Mark Lam from Hewlett-Packard Development Company, LP Review URL: http://codereview.chromium.org/6240002/ Relanded with Windows compilation issues fixed. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6401 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
ac0b1ded7b
commit
7984684ec9
@ -215,6 +215,7 @@ class PosixMemoryMappedFile : public OS::MemoryMappedFile {
|
||||
: file_(file), memory_(memory), size_(size) { }
|
||||
virtual ~PosixMemoryMappedFile();
|
||||
virtual void* memory() { return memory_; }
|
||||
virtual int size() { return size_; }
|
||||
private:
|
||||
FILE* file_;
|
||||
void* memory_;
|
||||
@ -222,6 +223,19 @@ class PosixMemoryMappedFile : public OS::MemoryMappedFile {
|
||||
};
|
||||
|
||||
|
||||
OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) {
|
||||
FILE* file = fopen(name, "w+");
|
||||
if (file == NULL) return NULL;
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
int size = ftell(file);
|
||||
|
||||
void* memory =
|
||||
mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0);
|
||||
return new PosixMemoryMappedFile(file, memory, size);
|
||||
}
|
||||
|
||||
|
||||
OS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size,
|
||||
void* initial) {
|
||||
FILE* file = fopen(name, "w+");
|
||||
|
@ -318,6 +318,7 @@ class PosixMemoryMappedFile : public OS::MemoryMappedFile {
|
||||
: file_(file), memory_(memory), size_(size) { }
|
||||
virtual ~PosixMemoryMappedFile();
|
||||
virtual void* memory() { return memory_; }
|
||||
virtual int size() { return size_; }
|
||||
private:
|
||||
FILE* file_;
|
||||
void* memory_;
|
||||
@ -325,6 +326,19 @@ class PosixMemoryMappedFile : public OS::MemoryMappedFile {
|
||||
};
|
||||
|
||||
|
||||
OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) {
|
||||
FILE* file = fopen(name, "w+");
|
||||
if (file == NULL) return NULL;
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
int size = ftell(file);
|
||||
|
||||
void* memory =
|
||||
mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0);
|
||||
return new PosixMemoryMappedFile(file, memory, size);
|
||||
}
|
||||
|
||||
|
||||
OS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size,
|
||||
void* initial) {
|
||||
FILE* file = fopen(name, "w+");
|
||||
|
@ -196,6 +196,7 @@ class PosixMemoryMappedFile : public OS::MemoryMappedFile {
|
||||
: file_(file), memory_(memory), size_(size) { }
|
||||
virtual ~PosixMemoryMappedFile();
|
||||
virtual void* memory() { return memory_; }
|
||||
virtual int size() { return size_; }
|
||||
private:
|
||||
FILE* file_;
|
||||
void* memory_;
|
||||
@ -203,6 +204,19 @@ class PosixMemoryMappedFile : public OS::MemoryMappedFile {
|
||||
};
|
||||
|
||||
|
||||
OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) {
|
||||
FILE* file = fopen(name, "w+");
|
||||
if (file == NULL) return NULL;
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
int size = ftell(file);
|
||||
|
||||
void* memory =
|
||||
mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0);
|
||||
return new PosixMemoryMappedFile(file, memory, size);
|
||||
}
|
||||
|
||||
|
||||
OS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size,
|
||||
void* initial) {
|
||||
FILE* file = fopen(name, "w+");
|
||||
|
@ -242,6 +242,12 @@ void OS::DebugBreak() {
|
||||
}
|
||||
|
||||
|
||||
OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) {
|
||||
UNIMPLEMENTED();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
OS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size,
|
||||
void* initial) {
|
||||
UNIMPLEMENTED();
|
||||
|
@ -213,6 +213,7 @@ class PosixMemoryMappedFile : public OS::MemoryMappedFile {
|
||||
: file_(file), memory_(memory), size_(size) { }
|
||||
virtual ~PosixMemoryMappedFile();
|
||||
virtual void* memory() { return memory_; }
|
||||
virtual int size() { return size_; }
|
||||
private:
|
||||
FILE* file_;
|
||||
void* memory_;
|
||||
@ -220,6 +221,19 @@ class PosixMemoryMappedFile : public OS::MemoryMappedFile {
|
||||
};
|
||||
|
||||
|
||||
OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) {
|
||||
FILE* file = fopen(name, "w+");
|
||||
if (file == NULL) return NULL;
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
int size = ftell(file);
|
||||
|
||||
void* memory =
|
||||
mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0);
|
||||
return new PosixMemoryMappedFile(file, memory, size);
|
||||
}
|
||||
|
||||
|
||||
OS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size,
|
||||
void* initial) {
|
||||
FILE* file = fopen(name, "w+");
|
||||
|
@ -122,6 +122,11 @@ FILE* OS::FOpen(const char* path, const char* mode) {
|
||||
}
|
||||
|
||||
|
||||
bool OS::Remove(const char* path) {
|
||||
return (remove(path) == 0);
|
||||
}
|
||||
|
||||
|
||||
const char* OS::LogFileOpenMode = "w";
|
||||
|
||||
|
||||
|
@ -226,6 +226,7 @@ class PosixMemoryMappedFile : public OS::MemoryMappedFile {
|
||||
: file_(file), memory_(memory), size_(size) { }
|
||||
virtual ~PosixMemoryMappedFile();
|
||||
virtual void* memory() { return memory_; }
|
||||
virtual int size() { return size_; }
|
||||
private:
|
||||
FILE* file_;
|
||||
void* memory_;
|
||||
@ -233,6 +234,19 @@ class PosixMemoryMappedFile : public OS::MemoryMappedFile {
|
||||
};
|
||||
|
||||
|
||||
OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) {
|
||||
FILE* file = fopen(name, "w+");
|
||||
if (file == NULL) return NULL;
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
int size = ftell(file);
|
||||
|
||||
void* memory =
|
||||
mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0);
|
||||
return new PosixMemoryMappedFile(file, memory, size);
|
||||
}
|
||||
|
||||
|
||||
OS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size,
|
||||
void* initial) {
|
||||
FILE* file = fopen(name, "w+");
|
||||
|
@ -670,6 +670,11 @@ FILE* OS::FOpen(const char* path, const char* mode) {
|
||||
}
|
||||
|
||||
|
||||
bool OS::Remove(const char* path) {
|
||||
return (DeleteFile(path) != 0);
|
||||
}
|
||||
|
||||
|
||||
// Open log file in binary mode to avoid /n -> /r/n conversion.
|
||||
const char* OS::LogFileOpenMode = "wb";
|
||||
|
||||
@ -911,17 +916,44 @@ void OS::DebugBreak() {
|
||||
|
||||
class Win32MemoryMappedFile : public OS::MemoryMappedFile {
|
||||
public:
|
||||
Win32MemoryMappedFile(HANDLE file, HANDLE file_mapping, void* memory)
|
||||
: file_(file), file_mapping_(file_mapping), memory_(memory) { }
|
||||
Win32MemoryMappedFile(HANDLE file,
|
||||
HANDLE file_mapping,
|
||||
void* memory,
|
||||
int size)
|
||||
: file_(file),
|
||||
file_mapping_(file_mapping),
|
||||
memory_(memory),
|
||||
size_(size) { }
|
||||
virtual ~Win32MemoryMappedFile();
|
||||
virtual void* memory() { return memory_; }
|
||||
virtual int size() { return size_; }
|
||||
private:
|
||||
HANDLE file_;
|
||||
HANDLE file_mapping_;
|
||||
void* memory_;
|
||||
int size_;
|
||||
};
|
||||
|
||||
|
||||
OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) {
|
||||
// Open a physical file
|
||||
HANDLE file = CreateFileA(name, GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (file == NULL) return NULL;
|
||||
|
||||
int size = static_cast<int>(GetFileSize(file, NULL));
|
||||
|
||||
// Create a file mapping for the physical file
|
||||
HANDLE file_mapping = CreateFileMapping(file, NULL,
|
||||
PAGE_READWRITE, 0, static_cast<DWORD>(size), NULL);
|
||||
if (file_mapping == NULL) return NULL;
|
||||
|
||||
// Map a view of the file into memory
|
||||
void* memory = MapViewOfFile(file_mapping, FILE_MAP_ALL_ACCESS, 0, 0, size);
|
||||
return new Win32MemoryMappedFile(file, file_mapping, memory, size);
|
||||
}
|
||||
|
||||
|
||||
OS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size,
|
||||
void* initial) {
|
||||
// Open a physical file
|
||||
@ -935,7 +967,7 @@ OS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size,
|
||||
// Map a view of the file into memory
|
||||
void* memory = MapViewOfFile(file_mapping, FILE_MAP_ALL_ACCESS, 0, 0, size);
|
||||
if (memory) memmove(memory, initial, size);
|
||||
return new Win32MemoryMappedFile(file, file_mapping, memory);
|
||||
return new Win32MemoryMappedFile(file, file_mapping, memory, size);
|
||||
}
|
||||
|
||||
|
||||
|
@ -174,6 +174,7 @@ class OS {
|
||||
static int GetLastError();
|
||||
|
||||
static FILE* FOpen(const char* path, const char* mode);
|
||||
static bool Remove(const char* path);
|
||||
|
||||
// Log file open mode is platform-dependent due to line ends issues.
|
||||
static const char* LogFileOpenMode;
|
||||
@ -251,9 +252,11 @@ class OS {
|
||||
|
||||
class MemoryMappedFile {
|
||||
public:
|
||||
static MemoryMappedFile* open(const char* name);
|
||||
static MemoryMappedFile* create(const char* name, int size, void* initial);
|
||||
virtual ~MemoryMappedFile() { }
|
||||
virtual void* memory() = 0;
|
||||
virtual int size() = 0;
|
||||
};
|
||||
|
||||
// Safe formatting print. Ensures that str is always null-terminated.
|
||||
|
92
src/utils.cc
92
src/utils.cc
@ -276,4 +276,96 @@ char* StringBuilder::Finalize() {
|
||||
}
|
||||
|
||||
|
||||
MemoryMappedExternalResource::MemoryMappedExternalResource(const char* filename)
|
||||
: filename_(NULL),
|
||||
data_(NULL),
|
||||
length_(0),
|
||||
remove_file_on_cleanup_(false) {
|
||||
Init(filename);
|
||||
}
|
||||
|
||||
|
||||
MemoryMappedExternalResource::
|
||||
MemoryMappedExternalResource(const char* filename,
|
||||
bool remove_file_on_cleanup)
|
||||
: filename_(NULL),
|
||||
data_(NULL),
|
||||
length_(0),
|
||||
remove_file_on_cleanup_(remove_file_on_cleanup) {
|
||||
Init(filename);
|
||||
}
|
||||
|
||||
|
||||
MemoryMappedExternalResource::~MemoryMappedExternalResource() {
|
||||
// Release the resources if we had successfully acquired them:
|
||||
if (file_ != NULL) {
|
||||
delete file_;
|
||||
if (remove_file_on_cleanup_) {
|
||||
OS::Remove(filename_);
|
||||
}
|
||||
DeleteArray<char>(filename_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MemoryMappedExternalResource::Init(const char* filename) {
|
||||
file_ = OS::MemoryMappedFile::open(filename);
|
||||
if (file_ != NULL) {
|
||||
filename_ = StrDup(filename);
|
||||
data_ = reinterpret_cast<char*>(file_->memory());
|
||||
length_ = file_->size();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool MemoryMappedExternalResource::EnsureIsAscii(bool abort_if_failed) const {
|
||||
bool is_ascii = true;
|
||||
|
||||
int line_no = 1;
|
||||
const char* start_of_line = data_;
|
||||
const char* end = data_ + length_;
|
||||
for (const char* p = data_; p < end; p++) {
|
||||
char c = *p;
|
||||
if ((c & 0x80) != 0) {
|
||||
// Non-ascii detected:
|
||||
is_ascii = false;
|
||||
|
||||
// Report the error and abort if appropriate:
|
||||
if (abort_if_failed) {
|
||||
intptr_t char_no = (p - start_of_line) - 1;
|
||||
|
||||
ASSERT(filename_ != NULL);
|
||||
PrintF("\n\n\n"
|
||||
"Abort: Non-Ascii character 0x%.2x in file %s line %d char %d",
|
||||
c, filename_, line_no, char_no);
|
||||
|
||||
// Allow for some context up to kNumberOfLeadingContextChars chars
|
||||
// before the offending non-ascii char to help the user see where
|
||||
// the offending char is.
|
||||
const int kNumberOfLeadingContextChars = 10;
|
||||
const char* err_context = p - kNumberOfLeadingContextChars;
|
||||
if (err_context < data_) {
|
||||
err_context = data_;
|
||||
}
|
||||
// Compute the length of the error context and print it.
|
||||
intptr_t err_context_length = p - err_context;
|
||||
if (err_context_length != 0) {
|
||||
PrintF(" after \"%.*s\"", err_context_length, err_context);
|
||||
}
|
||||
PrintF(".\n\n\n");
|
||||
OS::Abort();
|
||||
}
|
||||
|
||||
break; // Non-ascii detected. No need to continue scanning.
|
||||
}
|
||||
if (c == '\n') {
|
||||
start_of_line = p;
|
||||
line_no++;
|
||||
}
|
||||
}
|
||||
|
||||
return is_ascii;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
@ -316,6 +316,39 @@ static inline void CopyChars(sinkchar* dest, const sourcechar* src, int chars) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// A resource for using mmapped files to back external strings that are read
|
||||
// from files.
|
||||
class MemoryMappedExternalResource: public
|
||||
v8::String::ExternalAsciiStringResource {
|
||||
public:
|
||||
explicit MemoryMappedExternalResource(const char* filename);
|
||||
MemoryMappedExternalResource(const char* filename,
|
||||
bool remove_file_on_cleanup);
|
||||
virtual ~MemoryMappedExternalResource();
|
||||
|
||||
virtual const char* data() const { return data_; }
|
||||
virtual size_t length() const { return length_; }
|
||||
|
||||
bool exists() const { return file_ != NULL; }
|
||||
bool is_empty() const { return length_ == 0; }
|
||||
|
||||
bool EnsureIsAscii(bool abort_if_failed) const;
|
||||
bool EnsureIsAscii() const { return EnsureIsAscii(true); }
|
||||
bool IsAscii() const { return EnsureIsAscii(false); }
|
||||
|
||||
private:
|
||||
void Init(const char* filename);
|
||||
|
||||
char* filename_;
|
||||
OS::MemoryMappedFile* file_;
|
||||
|
||||
const char* data_;
|
||||
size_t length_;
|
||||
bool remove_file_on_cleanup_;
|
||||
};
|
||||
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
||||
#endif // V8_V8UTILS_H_
|
||||
|
Loading…
Reference in New Issue
Block a user