Reviewers: Vyacheslav Egorov,
http://codereview.chromium.org/9634005/diff/1/src/spaces.cc
File src/spaces.cc (left):
http://codereview.chromium.org/9634005/diff/1/src/spaces.cc#oldcode2625
src/spaces.cc:2625:
On 2012/03/08 11:41:23, Vyacheslav Egorov wrote:
accidental edit? please revert.
Done.
http://codereview.chromium.org/9634005/diff/1/src/spaces.cc
File src/spaces.cc (right):
http://codereview.chromium.org/9634005/diff/1/src/spaces.cc#newcode2523
src/spaces.cc:2523: static bool match(void* key1, void* key2) {
On 2012/03/08 11:41:23, Vyacheslav Egorov wrote:
Please give this function a more meaningful name, e.g.
ComparePointers/SamePointers/etc
Done.
http://codereview.chromium.org/9634005/diff/1/src/spaces.cc#newcode2526
src/spaces.cc:2526:
On 2012/03/08 11:41:23, Vyacheslav Egorov wrote:
one additional empty line
Done.
http://codereview.chromium.org/9634005/diff/1/src/spaces.cc#newcode2588
src/spaces.cc:2588: // map following entries to this page object, in
which keys are
On 2012/03/08 11:41:23, Vyacheslav Egorov wrote:
comments should start with a capital letter and end with a dot.
Done.
http://codereview.chromium.org/9634005/diff/1/src/spaces.cc#newcode2595
src/spaces.cc:2595: key += MemoryChunk::kAlignment, hash++) {
On 2012/03/08 11:41:23, Vyacheslav Egorov wrote:
I think you can just unify hash and key (make key == hash) because key
is
aligned and it's 20 less significant bits are always zeros. This will
make this
loop cleaner.
Done.
http://codereview.chromium.org/9634005/diff/1/src/spaces.cc#newcode2596
src/spaces.cc:2596: (map_.Lookup(reinterpret_cast<void*>(key), hash,
true))->value = page;
On 2012/03/08 11:41:23, Vyacheslav Egorov wrote:
I would prefer this is done in two lines instead of a single line.
Done.
http://codereview.chromium.org/9634005/diff/1/src/spaces.cc#newcode2624
src/spaces.cc:2624: if ( page_address <= a && a < page_address +
page->size() ) {
On 2012/03/08 11:41:23, Vyacheslav Egorov wrote:
accidental edit? please revert.
Done.
http://codereview.chromium.org/9634005/diff/1/src/spaces.cc#newcode2642
src/spaces.cc:2642: return page;
On 2012/03/08 11:41:23, Vyacheslav Egorov wrote:
This code is duplicated in two places. Please move everything to a
single helper
function.
Accepted, will reduce FindObject(a) size by calling this function
instead to remove duplicated code
http://codereview.chromium.org/9634005/diff/1/src/spaces.cc#newcode2679
src/spaces.cc:2679: // remove entries belonging to this page
On 2012/03/08 11:41:23, Vyacheslav Egorov wrote:
comments should start with a capital letter and end with a dot.
Done.
http://codereview.chromium.org/9634005/diff/7002/src/spaces.cc
File src/spaces.cc (right):
http://codereview.chromium.org/9634005/diff/7002/src/spaces.cc#newcode2591
src/spaces.cc:2591: uint32_t base =
reinterpret_cast<uint32_t>(page)/MemoryChunk::kAlignment;
On 2012/03/09 12:15:37, Vyacheslav Egorov wrote:
casting page to uint32_t is not suitable for 64-bit arch.
consider using uintptr_t instead.
Done.
http://codereview.chromium.org/9634005/diff/7002/src/spaces.cc#newcode2616
src/spaces.cc:2616: LargePage* page = FindPageContainingPc(a);
On 2012/03/09 12:15:37, Vyacheslav Egorov wrote:
I would suggest retaining FindPageContainingPc because you are calling
it from
the function that is used for arbitrary addresses.
Not very sure if I catch your point. Please allow me to confirm. Do you
suggest retaining the linear search of FindPageContainingPc() and just
change FindObject() to hash lookup, or reversed, or something else ?
Thanks a lot for your answering
http://codereview.chromium.org/9634005/diff/7002/src/spaces.cc#newcode2633
src/spaces.cc:2633: if (page_address <= pc && pc < page_address +
page->size()) {
On 2012/03/09 12:15:37, Vyacheslav Egorov wrote:
Consider using page->Contains(pc) here.
The check range of page->Contains(pc) falls into
(base+Page::kObjectStartOffset, base+chunk_size), so if pc falls into
page's header range (base, base+Page::kObjectStartOffset) will be
failed, which would succeed otherwise. Should we allow this difference
and replace it with Contains() anyway ?
http://codereview.chromium.org/9634005/diff/7002/src/spaces.cc#newcode2673
src/spaces.cc:2673: uint32_t base =
reinterpret_cast<uint32_t>(page)/MemoryChunk::kAlignment;
On 2012/03/09 12:15:37, Vyacheslav Egorov wrote:
casting page to uint32_t is not suitable for 64-bit arch.
consider using uintptr_t instead.
Done.
Description:
Implement a hash based look-up to speed up containing address check in large
object space. Before, it was a link-list based look-up, and make this
function
a little bit 'hot' from profile point.
BUG=v8:853
TEST=
Please review this at http://codereview.chromium.org/9634005/
SVN Base: http://v8.googlecode.com/svn/trunk/
Affected files:
M src/spaces.h
M src/spaces.cc
Index: src/spaces.cc
===================================================================
--- src/spaces.cc (revision 10961)
+++ src/spaces.cc (working copy)
@@ -2520,7 +2520,11 @@
//
-----------------------------------------------------------------------------
// LargeObjectSpace
+static bool ComparePointers(void* key1, void* key2) {
+ return key1 == key2;
+}
+
LargeObjectSpace::LargeObjectSpace(Heap* heap,
intptr_t max_capacity,
AllocationSpace id)
@@ -2529,7 +2533,8 @@
first_page_(NULL),
size_(0),
page_count_(0),
- objects_size_(0) {}
+ objects_size_(0),
+ chunk_map_(ComparePointers, 1024) {}
bool LargeObjectSpace::SetUp() {
@@ -2537,6 +2542,7 @@
size_ = 0;
page_count_ = 0;
objects_size_ = 0;
+ chunk_map_.Clear();
return true;
}
@@ -2580,6 +2586,17 @@
page->set_next_page(first_page_);
first_page_ = page;
+ // Register all MemoryChunk::kAlignment-aligned chunks covered by
+ // this large page in the chunk map.
+ uint32_t base = reinterpret_cast<uint32_t>(page)/MemoryChunk::kAlignment;
+ uint32_t limit = base + (page->size()-1)/MemoryChunk::kAlignment;
+ for (uint32_t key = base; key <= limit; key++) {
+ HashMap::Entry* entry = chunk_map_.Lookup(reinterpret_cast<void*>(key),
+ key, true);
+ ASSERT(entry != NULL);
+ entry->value = page;
+ }
+
HeapObject* object = page->GetObject();
#ifdef DEBUG
@@ -2596,27 +2613,25 @@
// GC support
MaybeObject* LargeObjectSpace::FindObject(Address a) {
- for (LargePage* page = first_page_;
- page != NULL;
- page = page->next_page()) {
- Address page_address = page->address();
- if (page_address <= a && a < page_address + page->size()) {
- return page->GetObject();
- }
+ LargePage* page = FindPageContainingPc(a);
+ if (page != NULL) {
+ return page->GetObject();
}
return Failure::Exception();
}
LargePage* LargeObjectSpace::FindPageContainingPc(Address pc) {
- // TODO(853): Change this implementation to only find executable
- // chunks and use some kind of hash-based approach to speed it up.
- for (LargePage* chunk = first_page_;
- chunk != NULL;
- chunk = chunk->next_page()) {
- Address chunk_address = chunk->address();
- if (chunk_address <= pc && pc < chunk_address + chunk->size()) {
- return chunk;
+ uint32_t key = reinterpret_cast<uint32_t>(pc) / MemoryChunk::kAlignment;
+ HashMap::Entry* e = chunk_map_.Lookup(reinterpret_cast<void*>(key),
+ key, false);
+ if (e != NULL) {
+ ASSERT(e->value != NULL);
+ LargePage* page = reinterpret_cast<LargePage*>(e->value);
+ ASSERT(page->is_valid());
+ Address page_address = page->address();
+ if (page_address <= pc && pc < page_address + page->size()) {
+ return page;
}
}
return NULL;
@@ -2654,6 +2669,13 @@
objects_size_ -= object->Size();
page_count_--;
+ // Remove entries belonging to this page.
+ uint32_t base =
reinterpret_cast<uint32_t>(page)/MemoryChunk::kAlignment;
+ uint32_t limit = base + (page->size()-1)/MemoryChunk::kAlignment;
+ for (uint32_t key = base; key <= limit; key++) {
+ chunk_map_.Remove(reinterpret_cast<void*>(key), key);
+ }
+
if (is_pointer_object) {
heap()->QueueMemoryChunkForFree(page);
} else {
Index: src/spaces.h
===================================================================
--- src/spaces.h (revision 10961)
+++ src/spaces.h (working copy)
@@ -29,6 +29,7 @@
#define V8_SPACES_H_
#include "allocation.h"
+#include "hashmap.h"
#include "list.h"
#include "log.h"
@@ -2536,6 +2537,8 @@
intptr_t size_; // allocated bytes
int page_count_; // number of chunks
intptr_t objects_size_; // size of objects
+ // Map MemoryChunk::kAlignment-aligned chunks to large pages covering
them
+ HashMap chunk_map_;
friend class LargeObjectIterator;
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev