summaryrefslogtreecommitdiff
path: root/deps/v8/src/arm/simulator-arm.cc
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2010-04-27 00:31:47 -0700
committerRyan Dahl <ry@tinyclouds.org>2010-04-27 00:31:47 -0700
commit24931f840544c9970203660121a1ec4606bdd4f1 (patch)
treef22539325eb06fc50879d9d4f327cf6c83645891 /deps/v8/src/arm/simulator-arm.cc
parent2374e557e30fab5c357d3f03716ca3b83131c3c0 (diff)
downloadnode-new-24931f840544c9970203660121a1ec4606bdd4f1.tar.gz
Upgrade V8 to 2.2.5
Diffstat (limited to 'deps/v8/src/arm/simulator-arm.cc')
-rw-r--r--deps/v8/src/arm/simulator-arm.cc101
1 files changed, 100 insertions, 1 deletions
diff --git a/deps/v8/src/arm/simulator-arm.cc b/deps/v8/src/arm/simulator-arm.cc
index 827a88f356..b44a73804b 100644
--- a/deps/v8/src/arm/simulator-arm.cc
+++ b/deps/v8/src/arm/simulator-arm.cc
@@ -474,6 +474,96 @@ void Debugger::Debug() {
}
+static bool ICacheMatch(void* one, void* two) {
+ ASSERT((reinterpret_cast<intptr_t>(one) & CachePage::kPageMask) == 0);
+ ASSERT((reinterpret_cast<intptr_t>(two) & CachePage::kPageMask) == 0);
+ return one == two;
+}
+
+
+static uint32_t ICacheHash(void* key) {
+ return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)) >> 2;
+}
+
+
+static bool AllOnOnePage(uintptr_t start, int size) {
+ intptr_t start_page = (start & ~CachePage::kPageMask);
+ intptr_t end_page = ((start + size) & ~CachePage::kPageMask);
+ return start_page == end_page;
+}
+
+
+void Simulator::FlushICache(void* start_addr, size_t size) {
+ intptr_t start = reinterpret_cast<intptr_t>(start_addr);
+ int intra_line = (start & CachePage::kLineMask);
+ start -= intra_line;
+ size += intra_line;
+ size = ((size - 1) | CachePage::kLineMask) + 1;
+ int offset = (start & CachePage::kPageMask);
+ while (!AllOnOnePage(start, size - 1)) {
+ int bytes_to_flush = CachePage::kPageSize - offset;
+ FlushOnePage(start, bytes_to_flush);
+ start += bytes_to_flush;
+ size -= bytes_to_flush;
+ ASSERT_EQ(0, start & CachePage::kPageMask);
+ offset = 0;
+ }
+ if (size != 0) {
+ FlushOnePage(start, size);
+ }
+}
+
+
+CachePage* Simulator::GetCachePage(void* page) {
+ v8::internal::HashMap::Entry* entry = i_cache_->Lookup(page,
+ ICacheHash(page),
+ true);
+ if (entry->value == NULL) {
+ CachePage* new_page = new CachePage();
+ entry->value = new_page;
+ }
+ return reinterpret_cast<CachePage*>(entry->value);
+}
+
+
+// Flush from start up to and not including start + size.
+void Simulator::FlushOnePage(intptr_t start, int size) {
+ ASSERT(size <= CachePage::kPageSize);
+ ASSERT(AllOnOnePage(start, size - 1));
+ ASSERT((start & CachePage::kLineMask) == 0);
+ ASSERT((size & CachePage::kLineMask) == 0);
+ void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask));
+ int offset = (start & CachePage::kPageMask);
+ CachePage* cache_page = GetCachePage(page);
+ char* valid_bytemap = cache_page->ValidityByte(offset);
+ memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift);
+}
+
+
+void Simulator::CheckICache(Instr* instr) {
+#ifdef DEBUG
+ intptr_t address = reinterpret_cast<intptr_t>(instr);
+ void* page = reinterpret_cast<void*>(address & (~CachePage::kPageMask));
+ void* line = reinterpret_cast<void*>(address & (~CachePage::kLineMask));
+ int offset = (address & CachePage::kPageMask);
+ CachePage* cache_page = GetCachePage(page);
+ char* cache_valid_byte = cache_page->ValidityByte(offset);
+ bool cache_hit = (*cache_valid_byte == CachePage::LINE_VALID);
+ char* cached_line = cache_page->CachedData(offset & ~CachePage::kLineMask);
+ if (cache_hit) {
+ // Check that the data in memory matches the contents of the I-cache.
+ CHECK(memcmp(reinterpret_cast<void*>(instr),
+ cache_page->CachedData(offset),
+ Instr::kInstrSize) == 0);
+ } else {
+ // Cache miss. Load memory into the cache.
+ memcpy(cached_line, line, CachePage::kLineLength);
+ *cache_valid_byte = CachePage::LINE_VALID;
+ }
+#endif
+}
+
+
// Create one simulator per thread and keep it in thread local storage.
static v8::internal::Thread::LocalStorageKey simulator_key;
@@ -489,7 +579,13 @@ void Simulator::Initialize() {
}
+v8::internal::HashMap* Simulator::i_cache_ = NULL;
+
+
Simulator::Simulator() {
+ if (i_cache_ == NULL) {
+ i_cache_ = new v8::internal::HashMap(&ICacheMatch);
+ }
Initialize();
// Setup simulator support first. Some of this information is needed to
// setup the architecture state.
@@ -554,6 +650,9 @@ class Redirection {
swi_instruction_((AL << 28) | (0xf << 24) | call_rt_redirected),
fp_return_(fp_return),
next_(list_) {
+ Simulator::current()->
+ FlushICache(reinterpret_cast<void*>(&swi_instruction_),
+ Instr::kInstrSize);
list_ = this;
}
@@ -2342,6 +2441,7 @@ void Simulator::DecodeType6CoprocessorIns(Instr* instr) {
// Executes the current instruction.
void Simulator::InstructionDecode(Instr* instr) {
+ CheckICache(instr);
pc_modified_ = false;
if (::v8::internal::FLAG_trace_sim) {
disasm::NameConverter converter;
@@ -2536,7 +2636,6 @@ uintptr_t Simulator::PopAddress() {
return address;
}
-
} } // namespace assembler::arm
#endif // __arm__