From a8f7b1a0a0185d4fc2a6069d6095b28411a98ece Mon Sep 17 00:00:00 2001 From: Steven Johnson Date: Tue, 22 Dec 2009 17:32:49 -0800 Subject: [PATCH] speed up AR::validate (r=nnethercote,bug=473769) --HG-- extra : convert_revision : 0ff411e99654f590121e90a93345257b14442721 --- js/src/nanojit/Assembler.cpp | 42 +++++++++++++++++++++++++++++------- js/src/nanojit/Assembler.h | 6 ++++-- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/js/src/nanojit/Assembler.cpp b/js/src/nanojit/Assembler.cpp index a980c4b6d168..2a2eff565f5d 100755 --- a/js/src/nanojit/Assembler.cpp +++ b/js/src/nanojit/Assembler.cpp @@ -91,7 +91,21 @@ namespace nanojit /*static*/ LIns* const AR::BAD_ENTRY = (LIns*)0xdeadbeef; - void AR::validate() + void AR::validateQuick() + { + NanoAssert(_highWaterMark < NJ_MAX_STACK_ENTRY); + NanoAssert(_entries[0] == NULL); + // Only check a few entries around _highWaterMark. + uint32_t const RADIUS = 4; + uint32_t const lo = (_highWaterMark > 1 + RADIUS ? _highWaterMark - RADIUS : 1); + uint32_t const hi = (_highWaterMark + 1 + RADIUS < NJ_MAX_STACK_ENTRY ? _highWaterMark + 1 + RADIUS : NJ_MAX_STACK_ENTRY); + for (uint32_t i = lo; i <= _highWaterMark; ++i) + NanoAssert(_entries[i] != BAD_ENTRY); + for (uint32_t i = _highWaterMark+1; i < hi; ++i) + NanoAssert(_entries[i] == BAD_ENTRY); + } + + void AR::validateFull() { NanoAssert(_highWaterMark < NJ_MAX_STACK_ENTRY); NanoAssert(_entries[0] == NULL); @@ -101,6 +115,20 @@ namespace nanojit NanoAssert(_entries[i] == BAD_ENTRY); } + void AR::validate() + { + static uint32_t validateCounter = 0; + if (++validateCounter >= 100) + { + validateFull(); + validateCounter = 0; + } + else + { + validateQuick(); + } + } + #endif inline void AR::clear() @@ -266,8 +294,9 @@ namespace nanojit return idx > 0 && idx <= _highWaterMark && _entries[idx] == ins; } - void AR::checkForResourceConsistency(const RegAlloc& regs) const + void AR::checkForResourceConsistency(const RegAlloc& regs) { + validate(); for (uint32_t i = 1; i <= _highWaterMark; ++i) { LIns* ins = _entries[i]; @@ -1662,14 +1691,12 @@ namespace nanojit // NB: this loop relies on using entry[0] being NULL, // so that we are guaranteed to terminate // without access negative entries. - LIns *i = _entries[idx]; - NanoAssert(i != 0); + LIns* i = _entries[idx]; + NanoAssert(i != NULL); do { - _entries[idx] = 0; + _entries[idx] = NULL; idx--; } while (_entries[idx] == i); - - debug_only(validate();) } #ifdef NJ_VERBOSE @@ -1816,7 +1843,6 @@ namespace nanojit uint32_t Assembler::arReserve(LIns* ins) { uint32_t i = _activation.reserveEntry(ins); - debug_only( _activation.validate(); ) if (!i) setError(StackFull); return i; diff --git a/js/src/nanojit/Assembler.h b/js/src/nanojit/Assembler.h index c9ee5a15a1aa..d2d1e9f73669 100644 --- a/js/src/nanojit/Assembler.h +++ b/js/src/nanojit/Assembler.h @@ -124,9 +124,11 @@ namespace nanojit uint32_t reserveEntry(LIns* ins); /* return 0 if unable to reserve the entry */ #ifdef _DEBUG + void validateQuick(); + void validateFull(); void validate(); bool isValidEntry(uint32_t idx, LIns* ins) const; /* return true iff idx and ins are matched */ - void checkForResourceConsistency(const RegAlloc& regs) const; + void checkForResourceConsistency(const RegAlloc& regs); void checkForResourceLeaks() const; #endif @@ -143,7 +145,7 @@ namespace nanojit inline AR::AR() { - _entries[0] = 0; + _entries[0] = NULL; clear(); }