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

Side by Side Diff: src/arm/simulator-arm.cc

Issue 1523030: Add checks to the ARM simulator to ensure that we flush the icache all... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 8 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/simulator-arm.h ('k') | src/serialize.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 RedoBreakpoints(); 467 RedoBreakpoints();
468 468
469 #undef COMMAND_SIZE 469 #undef COMMAND_SIZE
470 #undef ARG_SIZE 470 #undef ARG_SIZE
471 471
472 #undef STR 472 #undef STR
473 #undef XSTR 473 #undef XSTR
474 } 474 }
475 475
476 476
477 static bool ICacheMatch(void* one, void* two) {
478 ASSERT((reinterpret_cast<intptr_t>(one) & CachePage::kPageMask) == 0);
479 ASSERT((reinterpret_cast<intptr_t>(two) & CachePage::kPageMask) == 0);
480 return one == two;
481 }
482
483
484 static uint32_t ICacheHash(void* key) {
485 return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)) >> 2;
486 }
487
488
489 static bool AllOnOnePage(uintptr_t start, int size) {
490 intptr_t start_page = (start & ~CachePage::kPageMask);
491 intptr_t end_page = ((start + size) & ~CachePage::kPageMask);
492 return start_page == end_page;
493 }
494
495
496 void Simulator::FlushICache(void* start_addr, size_t size) {
497 intptr_t start = reinterpret_cast<intptr_t>(start_addr);
498 int intra_line = (start & CachePage::kLineMask);
499 start -= intra_line;
500 size += intra_line;
501 size = ((size - 1) | CachePage::kLineMask) + 1;
502 int offset = (start & CachePage::kPageMask);
503 while (!AllOnOnePage(start, size - 1)) {
504 int bytes_to_flush = CachePage::kPageSize - offset;
505 FlushOnePage(start, bytes_to_flush);
506 start += bytes_to_flush;
507 size -= bytes_to_flush;
508 ASSERT_EQ(0, start & CachePage::kPageMask);
509 offset = 0;
510 }
511 if (size != 0) {
512 FlushOnePage(start, size);
513 }
514 }
515
516
517 CachePage* Simulator::GetCachePage(void* page) {
518 v8::internal::HashMap::Entry* entry = i_cache_->Lookup(page,
519 ICacheHash(page),
520 true);
521 if (entry->value == NULL) {
522 CachePage* new_page = new CachePage();
523 entry->value = new_page;
524 }
525 return reinterpret_cast<CachePage*>(entry->value);
526 }
527
528
529 // Flush from start up to and not including start + size.
530 void Simulator::FlushOnePage(intptr_t start, int size) {
531 ASSERT(size <= CachePage::kPageSize);
532 ASSERT(AllOnOnePage(start, size - 1));
533 ASSERT((start & CachePage::kLineMask) == 0);
534 ASSERT((size & CachePage::kLineMask) == 0);
535 void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask));
536 int offset = (start & CachePage::kPageMask);
537 CachePage* cache_page = GetCachePage(page);
538 char* valid_bytemap = cache_page->ValidityByte(offset);
539 memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift);
540 }
541
542
543 void Simulator::CheckICache(Instr* instr) {
544 #ifdef DEBUG
545 intptr_t address = reinterpret_cast<intptr_t>(instr);
546 void* page = reinterpret_cast<void*>(address & (~CachePage::kPageMask));
547 void* line = reinterpret_cast<void*>(address & (~CachePage::kLineMask));
548 int offset = (address & CachePage::kPageMask);
549 CachePage* cache_page = GetCachePage(page);
550 char* cache_valid_byte = cache_page->ValidityByte(offset);
551 bool cache_hit = (*cache_valid_byte == CachePage::LINE_VALID);
552 char* cached_line = cache_page->CachedData(offset & ~CachePage::kLineMask);
553 if (cache_hit) {
554 // Check that the data in memory matches the contents of the I-cache.
555 CHECK(memcmp(reinterpret_cast<void*>(instr),
556 cache_page->CachedData(offset),
557 Instr::kInstrSize) == 0);
558 } else {
559 // Cache miss. Load memory into the cache.
560 memcpy(cached_line, line, CachePage::kLineLength);
561 *cache_valid_byte = CachePage::LINE_VALID;
562 }
563 #endif
564 }
565
566
477 // Create one simulator per thread and keep it in thread local storage. 567 // Create one simulator per thread and keep it in thread local storage.
478 static v8::internal::Thread::LocalStorageKey simulator_key; 568 static v8::internal::Thread::LocalStorageKey simulator_key;
479 569
480 570
481 bool Simulator::initialized_ = false; 571 bool Simulator::initialized_ = false;
482 572
483 573
484 void Simulator::Initialize() { 574 void Simulator::Initialize() {
485 if (initialized_) return; 575 if (initialized_) return;
486 simulator_key = v8::internal::Thread::CreateThreadLocalKey(); 576 simulator_key = v8::internal::Thread::CreateThreadLocalKey();
487 initialized_ = true; 577 initialized_ = true;
488 ::v8::internal::ExternalReference::set_redirector(&RedirectExternalReference); 578 ::v8::internal::ExternalReference::set_redirector(&RedirectExternalReference);
489 } 579 }
490 580
491 581
582 v8::internal::HashMap* Simulator::i_cache_ = NULL;
583
584
492 Simulator::Simulator() { 585 Simulator::Simulator() {
586 if (i_cache_ == NULL) {
587 i_cache_ = new v8::internal::HashMap(&ICacheMatch);
588 }
493 Initialize(); 589 Initialize();
494 // Setup simulator support first. Some of this information is needed to 590 // Setup simulator support first. Some of this information is needed to
495 // setup the architecture state. 591 // setup the architecture state.
496 size_t stack_size = 1 * 1024*1024; // allocate 1MB for stack 592 size_t stack_size = 1 * 1024*1024; // allocate 1MB for stack
497 stack_ = reinterpret_cast<char*>(malloc(stack_size)); 593 stack_ = reinterpret_cast<char*>(malloc(stack_size));
498 pc_modified_ = false; 594 pc_modified_ = false;
499 icount_ = 0; 595 icount_ = 0;
500 break_pc_ = NULL; 596 break_pc_ = NULL;
501 break_instr_ = 0; 597 break_instr_ = 0;
502 598
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 // reference to a swi (software-interrupt) instruction that is handled by 643 // reference to a swi (software-interrupt) instruction that is handled by
548 // the simulator. We write the original destination of the jump just at a known 644 // the simulator. We write the original destination of the jump just at a known
549 // offset from the swi instruction so the simulator knows what to call. 645 // offset from the swi instruction so the simulator knows what to call.
550 class Redirection { 646 class Redirection {
551 public: 647 public:
552 Redirection(void* external_function, bool fp_return) 648 Redirection(void* external_function, bool fp_return)
553 : external_function_(external_function), 649 : external_function_(external_function),
554 swi_instruction_((AL << 28) | (0xf << 24) | call_rt_redirected), 650 swi_instruction_((AL << 28) | (0xf << 24) | call_rt_redirected),
555 fp_return_(fp_return), 651 fp_return_(fp_return),
556 next_(list_) { 652 next_(list_) {
653 Simulator::current()->
654 FlushICache(reinterpret_cast<void*>(&swi_instruction_),
655 Instr::kInstrSize);
557 list_ = this; 656 list_ = this;
558 } 657 }
559 658
560 void* address_of_swi_instruction() { 659 void* address_of_swi_instruction() {
561 return reinterpret_cast<void*>(&swi_instruction_); 660 return reinterpret_cast<void*>(&swi_instruction_);
562 } 661 }
563 662
564 void* external_function() { return external_function_; } 663 void* external_function() { return external_function_; }
565 bool fp_return() { return fp_return_; } 664 bool fp_return() { return fp_return_; }
566 665
(...skipping 1768 matching lines...) Expand 10 before | Expand all | Expand 10 after
2335 break; 2434 break;
2336 } 2435 }
2337 } else { 2436 } else {
2338 UNIMPLEMENTED(); // Not used by V8. 2437 UNIMPLEMENTED(); // Not used by V8.
2339 } 2438 }
2340 } 2439 }
2341 2440
2342 2441
2343 // Executes the current instruction. 2442 // Executes the current instruction.
2344 void Simulator::InstructionDecode(Instr* instr) { 2443 void Simulator::InstructionDecode(Instr* instr) {
2444 CheckICache(instr);
2345 pc_modified_ = false; 2445 pc_modified_ = false;
2346 if (::v8::internal::FLAG_trace_sim) { 2446 if (::v8::internal::FLAG_trace_sim) {
2347 disasm::NameConverter converter; 2447 disasm::NameConverter converter;
2348 disasm::Disassembler dasm(converter); 2448 disasm::Disassembler dasm(converter);
2349 // use a reasonably large buffer 2449 // use a reasonably large buffer
2350 v8::internal::EmbeddedVector<char, 256> buffer; 2450 v8::internal::EmbeddedVector<char, 256> buffer;
2351 dasm.InstructionDecode(buffer, 2451 dasm.InstructionDecode(buffer,
2352 reinterpret_cast<byte*>(instr)); 2452 reinterpret_cast<byte*>(instr));
2353 PrintF(" 0x%08x %s\n", instr, buffer.start()); 2453 PrintF(" 0x%08x %s\n", instr, buffer.start());
2354 } 2454 }
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
2529 2629
2530 2630
2531 uintptr_t Simulator::PopAddress() { 2631 uintptr_t Simulator::PopAddress() {
2532 int current_sp = get_register(sp); 2632 int current_sp = get_register(sp);
2533 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); 2633 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp);
2534 uintptr_t address = *stack_slot; 2634 uintptr_t address = *stack_slot;
2535 set_register(sp, current_sp + sizeof(uintptr_t)); 2635 set_register(sp, current_sp + sizeof(uintptr_t));
2536 return address; 2636 return address;
2537 } 2637 }
2538 2638
2539
2540 } } // namespace assembler::arm 2639 } } // namespace assembler::arm
2541 2640
2542 #endif // __arm__ 2641 #endif // __arm__
OLDNEW
« no previous file with comments | « src/arm/simulator-arm.h ('k') | src/serialize.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698