Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(108)

Unified Diff: test/cctest/test-log.cc

Issue 113641: Fix test-log/EquivalenceOfLoggingAndTraversal for the snapshot case. (Closed)
Patch Set: Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/cctest/test-log.cc
diff --git a/test/cctest/test-log.cc b/test/cctest/test-log.cc
index a7c3435184f7458b3a0dccbfd7a2704361c61054..d65a995a0d9abee580ce544b433d74d2ef516401 100644
--- a/test/cctest/test-log.cc
+++ b/test/cctest/test-log.cc
@@ -130,25 +130,6 @@ static bool Consume(const char* str, char** buf) {
}
-static void ParseAddress(char* start, Address* min_addr, Address* max_addr) {
- Address addr = reinterpret_cast<Address>(strtoul(start, NULL, 16)); // NOLINT
- if (addr < *min_addr) *min_addr = addr;
- if (addr > *max_addr) *max_addr = addr;
-}
-
-
-static Address ConsumeAddress(
- char** start, Address min_addr, Address max_addr) {
- char* end_ptr;
- Address addr =
- reinterpret_cast<Address>(strtoul(*start, &end_ptr, 16)); // NOLINT
- CHECK_GE(addr, min_addr);
- CHECK_GE(max_addr, addr);
- *start = end_ptr;
- return addr;
-}
-
-
namespace {
// A code entity is a pointer to a position of code-creation event in buffer log
@@ -156,48 +137,142 @@ namespace {
// comparing code entities pretty easy.
typedef char* CodeEntityInfo;
+class Interval {
+ public:
+ Interval()
+ : min_addr(reinterpret_cast<Address>(-1)),
+ max_addr(reinterpret_cast<Address>(0)), next(NULL) {}
+
+ ~Interval() { delete next; }
+
+ size_t Length() {
+ size_t result = max_addr - min_addr + 1;
+ if (next != NULL) result += next->Length();
+ return result;
+ }
+
+ void CloneFrom(Interval* src) {
+ while (src != NULL) {
+ RegisterAddress(src->min_addr);
+ RegisterAddress(src->max_addr);
+ src = src->next;
+ }
+ }
+
+ bool Contains(Address addr) {
+ if (min_addr <= addr && addr <= max_addr) {
+ return true;
+ }
+ if (next != NULL) return next->Contains(addr);
Søren Thygesen Gjesse 2009/05/25 08:45:53 Please add {}'s for one statement if. Maybe use an
Mikhail Naganov 2009/05/25 09:32:10 Usually, there is no 'next' at all. 'next' appears
+ return false;
+ }
+
+ size_t GetIndex(Address addr) {
+ if (min_addr <= addr && addr <= max_addr) {
+ return addr - min_addr;
+ }
+ CHECK_NE(NULL, next);
+ return (max_addr - min_addr + 1) + next->GetIndex(addr);
+ }
+
+ Address GetMinAddr() {
+ return next == NULL ? min_addr : i::Min(min_addr, next->GetMinAddr());
+ }
+
+ Address GetMaxAddr() {
+ return next == NULL ? max_addr : i::Max(max_addr, next->GetMaxAddr());
+ }
+
+ void RegisterAddress(Address addr) {
+ if (min_addr == reinterpret_cast<Address>(-1)
+ || (size_t)(addr > min_addr ?
+ addr - min_addr : min_addr - addr) < MAX_DELTA) {
+ if (addr < min_addr) min_addr = addr;
+ if (addr > max_addr) max_addr = addr;
+ } else {
+ if (next == NULL) next = new Interval();
+ next->RegisterAddress(addr);
+ }
+ }
+
+ Address raw_min_addr() { return min_addr; }
+
+ Address raw_max_addr() { return max_addr; }
+
+ Interval* get_next() { return next; }
+
+ private:
+ static const size_t MAX_DELTA = 0x100000;
+ Address min_addr;
Søren Thygesen Gjesse 2009/05/25 08:45:53 Missing trailing underscores?
Mikhail Naganov 2009/05/25 09:32:10 Done.
+ Address max_addr;
+ Interval* next;
+};
+
+
// A structure used to return log parsing results.
class ParseLogResult {
public:
ParseLogResult()
- : min_addr(reinterpret_cast<Address>(-1)),
- max_addr(reinterpret_cast<Address>(0)),
- entities_map(NULL), entities(NULL),
+ : entities_map(NULL), entities(NULL),
max_entities(0) {}
~ParseLogResult() {
- // See allocation code below.
- if (entities_map != NULL) {
- i::DeleteArray(entities_map - 1);
- }
+ i::DeleteArray(entities_map);
i::DeleteArray(entities);
}
void AllocateEntities() {
// Make sure that the test doesn't operate on a bogus log.
CHECK_GT(max_entities, 0);
- CHECK_GT(min_addr, 0);
- CHECK_GT(max_addr, min_addr);
+ CHECK_GT(bounds.GetMinAddr(), 0);
+ CHECK_GT(bounds.GetMaxAddr(), bounds.GetMinAddr());
entities = i::NewArray<CodeEntityInfo>(max_entities);
for (int i = 0; i < max_entities; ++i) {
entities[i] = NULL;
}
- // We're adding fake items at [-1] and [size + 1] to simplify
- // comparison code.
- const int map_length = max_addr - min_addr + 1 + 2; // 2 fakes.
+ const size_t map_length = bounds.Length();
entities_map = i::NewArray<int>(map_length);
- for (int i = 0; i < map_length; ++i) {
+ for (size_t i = 0; i < map_length; ++i) {
entities_map[i] = -1;
}
- entities_map += 1; // Hide the -1 item, this is compensated on delete.
}
- // Minimal code entity address.
- Address min_addr;
- // Maximal code entity address.
- Address max_addr;
- // Memory map of entities start addresses. Biased by min_addr.
+ bool HasIndexForAddress(Address addr) {
+ return bounds.Contains(addr);
+ }
+
+ size_t GetIndexForAddress(Address addr) {
+ CHECK(HasIndexForAddress(addr));
+ return bounds.GetIndex(addr);
+ }
+
+ CodeEntityInfo GetEntity(Address addr) {
+ if (HasIndexForAddress(addr)) {
+ size_t idx = GetIndexForAddress(addr);
+ int item = entities_map[idx];
+ return item != -1 ? entities[item] : NULL;
+ }
+ return NULL;
+ }
+
+ void ParseAddress(char* start) {
+ Address addr =
+ reinterpret_cast<Address>(strtoul(start, NULL, 16)); // NOLINT
+ bounds.RegisterAddress(addr);
+ }
+
+ Address ConsumeAddress(char** start) {
+ char* end_ptr;
+ Address addr =
+ reinterpret_cast<Address>(strtoul(*start, &end_ptr, 16)); // NOLINT
+ CHECK(HasIndexForAddress(addr));
+ *start = end_ptr;
+ return addr;
+ }
+
+ Interval bounds;
Søren Thygesen Gjesse 2009/05/25 08:45:53 Missing trailing underscores?
Mikhail Naganov 2009/05/25 09:32:10 Um, actually encapsulation is sort of leaking here
+ // Memory map of entities start addresses. Biased by bounds.min_addr.
int* entities_map;
// An array of code entities.
CodeEntityInfo* entities;
@@ -243,31 +318,32 @@ static void ParserCycle(
static void Pass1CodeCreation(char* start, char* end, ParseLogResult* result) {
- ParseAddress(start, &result->min_addr, &result->max_addr);
+ result->ParseAddress(start);
++result->max_entities;
}
static void Pass1CodeDelete(char* start, char* end, ParseLogResult* result) {
- ParseAddress(start, &result->min_addr, &result->max_addr);
+ result->ParseAddress(start);
}
static void Pass1CodeMove(char* start, char* end, ParseLogResult* result) {
+ result->ParseAddress(start);
// Skip old address.
while (start < end && *start != ',') ++start;
CHECK_GT(end, start);
++start; // Skip ','.
- ParseAddress(start, &result->min_addr, &result->max_addr);
+ result->ParseAddress(start);
}
static void Pass2CodeCreation(char* start, char* end, ParseLogResult* result) {
- Address addr = ConsumeAddress(&start, result->min_addr, result->max_addr);
+ Address addr = result->ConsumeAddress(&start);
CHECK_GT(end, start);
++start; // Skip ','.
- int idx = addr - result->min_addr;
+ size_t idx = result->GetIndexForAddress(addr);
result->entities_map[idx] = -1;
for (int i = 0; i < result->max_entities; ++i) {
// Find an empty slot and fill it.
@@ -283,8 +359,8 @@ static void Pass2CodeCreation(char* start, char* end, ParseLogResult* result) {
static void Pass2CodeDelete(char* start, char* end, ParseLogResult* result) {
- Address addr = ConsumeAddress(&start, result->min_addr, result->max_addr);
- int idx = addr - result->min_addr;
+ Address addr = result->ConsumeAddress(&start);
+ size_t idx = result->GetIndexForAddress(addr);
// There can be code deletes that are not related to JS code.
if (result->entities_map[idx] >= 0) {
result->entities[result->entities_map[idx]] = NULL;
@@ -294,15 +370,14 @@ static void Pass2CodeDelete(char* start, char* end, ParseLogResult* result) {
static void Pass2CodeMove(char* start, char* end, ParseLogResult* result) {
- Address from_addr = ConsumeAddress(
- &start, result->min_addr, result->max_addr);
+ Address from_addr = result->ConsumeAddress(&start);
CHECK_GT(end, start);
++start; // Skip ','.
- Address to_addr = ConsumeAddress(&start, result->min_addr, result->max_addr);
+ Address to_addr = result->ConsumeAddress(&start);
CHECK_GT(end, start);
- int from_idx = from_addr - result->min_addr;
- int to_idx = to_addr - result->min_addr;
+ size_t from_idx = result->GetIndexForAddress(from_addr);
+ size_t to_idx = result->GetIndexForAddress(to_addr);
// There can be code moves that are not related to JS code.
if (from_idx != to_idx && result->entities_map[from_idx] >= 0) {
CHECK_EQ(-1, result->entities_map[to_idx]);
@@ -318,7 +393,8 @@ static void ParseLog(char* start, char* end, ParseLogResult* result) {
Pass1CodeCreation, Pass1CodeDelete, Pass1CodeMove);
printf("min_addr: %p, max_addr: %p, entities: %d\n",
- result->min_addr, result->max_addr, result->max_entities);
+ result->bounds.GetMinAddr(), result->bounds.GetMaxAddr(),
+ result->max_entities);
result->AllocateEntities();
@@ -466,28 +542,24 @@ TEST(EquivalenceOfLoggingAndTraversal) {
ParseLog(new_log_start, new_log_start + new_log_size, &new_result);
// Test their actual equivalence.
+ Interval combined;
+ combined.CloneFrom(&ref_result.bounds);
+ combined.CloneFrom(&new_result.bounds);
+ Interval* iter = &combined;
bool results_equal = true;
- int ref_idx = -1, new_idx = -1, ref_inc = 1, new_inc = 1;
- while (ref_inc > 0 || new_inc > 0) {
- const Address ref_addr = ref_result.min_addr + ref_idx;
- const Address new_addr = new_result.min_addr + new_idx;
- ref_inc = ref_addr <= ref_result.max_addr && ref_addr <= new_addr ? 1 : 0;
- new_inc = new_addr <= new_result.max_addr && new_addr <= ref_addr ? 1 : 0;
- const int ref_item = ref_result.entities_map[ref_idx];
- const int new_item = new_result.entities_map[new_idx];
- if (ref_item != -1 || new_item != -1) {
- CodeEntityInfo ref_entity =
- ref_item != -1 ? ref_result.entities[ref_item] : NULL;
- CodeEntityInfo new_entity =
- new_item != -1 ? new_result.entities[new_item] : NULL;
- const bool equal = AreEntitiesEqual(ref_entity, new_entity);
- if (!equal) results_equal = false;
- PrintCodeEntitiesInfo(
- equal, ref_inc != 0 ? ref_addr : new_addr,
- ref_entity, new_entity);
+
+ while (iter != NULL) {
+ for (Address addr = iter->raw_min_addr();
+ addr <= iter->raw_max_addr(); ++addr) {
+ CodeEntityInfo ref_entity = ref_result.GetEntity(addr);
+ CodeEntityInfo new_entity = new_result.GetEntity(addr);
+ if (ref_entity != NULL || new_entity != NULL) {
+ const bool equal = AreEntitiesEqual(ref_entity, new_entity);
+ if (!equal) results_equal = false;
+ PrintCodeEntitiesInfo(equal, addr, ref_entity, new_entity);
+ }
}
- ref_idx += ref_inc;
- new_idx += new_inc;
+ iter = iter->get_next();
}
// Make sure that all log data is written prior crash due to CHECK failure.
fflush(stdout);
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698