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

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

Issue 2864032: [Isolates] Statics 7: ExternalReference*/Simulator/dtoa... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: rebase Created 10 years, 5 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/conversions.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 29 matching lines...) Expand all
40 40
41 // Only build the simulator if not compiling for real ARM hardware. 41 // Only build the simulator if not compiling for real ARM hardware.
42 namespace assembler { 42 namespace assembler {
43 namespace arm { 43 namespace arm {
44 44
45 using ::v8::internal::Object; 45 using ::v8::internal::Object;
46 using ::v8::internal::PrintF; 46 using ::v8::internal::PrintF;
47 using ::v8::internal::OS; 47 using ::v8::internal::OS;
48 using ::v8::internal::ReadLine; 48 using ::v8::internal::ReadLine;
49 using ::v8::internal::DeleteArray; 49 using ::v8::internal::DeleteArray;
50 using ::v8::internal::Isolate;
50 51
51 // This macro provides a platform independent use of sscanf. The reason for 52 // This macro provides a platform independent use of sscanf. The reason for
52 // SScanF not being implemented in a platform independent way through 53 // SScanF not being implemented in a platform independent way through
53 // ::v8::internal::OS in the same way as SNPrintF is that the 54 // ::v8::internal::OS in the same way as SNPrintF is that the
54 // Windows C Run-Time Library does not provide vsscanf. 55 // Windows C Run-Time Library does not provide vsscanf.
55 #define SScanF sscanf // NOLINT 56 #define SScanF sscanf // NOLINT
56 57
57 // The Debugger class is used by the simulator while debugging simulated ARM 58 // The Debugger class is used by the simulator while debugging simulated ARM
58 // code. 59 // code.
59 class Debugger { 60 class Debugger {
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 } 489 }
489 490
490 491
491 static bool AllOnOnePage(uintptr_t start, int size) { 492 static bool AllOnOnePage(uintptr_t start, int size) {
492 intptr_t start_page = (start & ~CachePage::kPageMask); 493 intptr_t start_page = (start & ~CachePage::kPageMask);
493 intptr_t end_page = ((start + size) & ~CachePage::kPageMask); 494 intptr_t end_page = ((start + size) & ~CachePage::kPageMask);
494 return start_page == end_page; 495 return start_page == end_page;
495 } 496 }
496 497
497 498
498 void Simulator::FlushICache(void* start_addr, size_t size) { 499 void Simulator::FlushICache(v8::internal::HashMap* i_cache,
500 void* start_addr,
501 size_t size) {
499 intptr_t start = reinterpret_cast<intptr_t>(start_addr); 502 intptr_t start = reinterpret_cast<intptr_t>(start_addr);
500 int intra_line = (start & CachePage::kLineMask); 503 int intra_line = (start & CachePage::kLineMask);
501 start -= intra_line; 504 start -= intra_line;
502 size += intra_line; 505 size += intra_line;
503 size = ((size - 1) | CachePage::kLineMask) + 1; 506 size = ((size - 1) | CachePage::kLineMask) + 1;
504 int offset = (start & CachePage::kPageMask); 507 int offset = (start & CachePage::kPageMask);
505 while (!AllOnOnePage(start, size - 1)) { 508 while (!AllOnOnePage(start, size - 1)) {
506 int bytes_to_flush = CachePage::kPageSize - offset; 509 int bytes_to_flush = CachePage::kPageSize - offset;
507 FlushOnePage(start, bytes_to_flush); 510 FlushOnePage(i_cache, start, bytes_to_flush);
508 start += bytes_to_flush; 511 start += bytes_to_flush;
509 size -= bytes_to_flush; 512 size -= bytes_to_flush;
510 ASSERT_EQ(0, start & CachePage::kPageMask); 513 ASSERT_EQ(0, start & CachePage::kPageMask);
511 offset = 0; 514 offset = 0;
512 } 515 }
513 if (size != 0) { 516 if (size != 0) {
514 FlushOnePage(start, size); 517 FlushOnePage(i_cache, start, size);
515 } 518 }
516 } 519 }
517 520
518 521
519 CachePage* Simulator::GetCachePage(void* page) { 522 CachePage* Simulator::GetCachePage(v8::internal::HashMap* i_cache, void* page) {
520 v8::internal::HashMap::Entry* entry = i_cache_->Lookup(page, 523 v8::internal::HashMap::Entry* entry = i_cache->Lookup(page,
521 ICacheHash(page), 524 ICacheHash(page),
522 true); 525 true);
523 if (entry->value == NULL) { 526 if (entry->value == NULL) {
524 CachePage* new_page = new CachePage(); 527 CachePage* new_page = new CachePage();
525 entry->value = new_page; 528 entry->value = new_page;
526 } 529 }
527 return reinterpret_cast<CachePage*>(entry->value); 530 return reinterpret_cast<CachePage*>(entry->value);
528 } 531 }
529 532
530 533
531 // Flush from start up to and not including start + size. 534 // Flush from start up to and not including start + size.
532 void Simulator::FlushOnePage(intptr_t start, int size) { 535 void Simulator::FlushOnePage(v8::internal::HashMap* i_cache,
536 intptr_t start,
537 int size) {
533 ASSERT(size <= CachePage::kPageSize); 538 ASSERT(size <= CachePage::kPageSize);
534 ASSERT(AllOnOnePage(start, size - 1)); 539 ASSERT(AllOnOnePage(start, size - 1));
535 ASSERT((start & CachePage::kLineMask) == 0); 540 ASSERT((start & CachePage::kLineMask) == 0);
536 ASSERT((size & CachePage::kLineMask) == 0); 541 ASSERT((size & CachePage::kLineMask) == 0);
537 void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask)); 542 void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask));
538 int offset = (start & CachePage::kPageMask); 543 int offset = (start & CachePage::kPageMask);
539 CachePage* cache_page = GetCachePage(page); 544 CachePage* cache_page = GetCachePage(i_cache, page);
540 char* valid_bytemap = cache_page->ValidityByte(offset); 545 char* valid_bytemap = cache_page->ValidityByte(offset);
541 memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift); 546 memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift);
542 } 547 }
543 548
544 549
545 void Simulator::CheckICache(Instr* instr) { 550 void Simulator::CheckICache(v8::internal::HashMap* i_cache, Instr* instr) {
546 intptr_t address = reinterpret_cast<intptr_t>(instr); 551 intptr_t address = reinterpret_cast<intptr_t>(instr);
547 void* page = reinterpret_cast<void*>(address & (~CachePage::kPageMask)); 552 void* page = reinterpret_cast<void*>(address & (~CachePage::kPageMask));
548 void* line = reinterpret_cast<void*>(address & (~CachePage::kLineMask)); 553 void* line = reinterpret_cast<void*>(address & (~CachePage::kLineMask));
549 int offset = (address & CachePage::kPageMask); 554 int offset = (address & CachePage::kPageMask);
550 CachePage* cache_page = GetCachePage(page); 555 CachePage* cache_page = GetCachePage(i_cache, page);
551 char* cache_valid_byte = cache_page->ValidityByte(offset); 556 char* cache_valid_byte = cache_page->ValidityByte(offset);
552 bool cache_hit = (*cache_valid_byte == CachePage::LINE_VALID); 557 bool cache_hit = (*cache_valid_byte == CachePage::LINE_VALID);
553 char* cached_line = cache_page->CachedData(offset & ~CachePage::kLineMask); 558 char* cached_line = cache_page->CachedData(offset & ~CachePage::kLineMask);
554 if (cache_hit) { 559 if (cache_hit) {
555 // Check that the data in memory matches the contents of the I-cache. 560 // Check that the data in memory matches the contents of the I-cache.
556 CHECK(memcmp(reinterpret_cast<void*>(instr), 561 CHECK(memcmp(reinterpret_cast<void*>(instr),
557 cache_page->CachedData(offset), 562 cache_page->CachedData(offset),
558 Instr::kInstrSize) == 0); 563 Instr::kInstrSize) == 0);
559 } else { 564 } else {
560 // Cache miss. Load memory into the cache. 565 // Cache miss. Load memory into the cache.
561 memcpy(cached_line, line, CachePage::kLineLength); 566 memcpy(cached_line, line, CachePage::kLineLength);
562 *cache_valid_byte = CachePage::LINE_VALID; 567 *cache_valid_byte = CachePage::LINE_VALID;
563 } 568 }
564 } 569 }
565 570
566 571
567 // Create one simulator per thread and keep it in thread local storage.
568 static v8::internal::Thread::LocalStorageKey simulator_key;
569
570
571 bool Simulator::initialized_ = false;
572
573
574 void Simulator::Initialize() { 572 void Simulator::Initialize() {
575 if (initialized_) return; 573 if (Isolate::Current()->simulator_initialized()) return;
576 simulator_key = v8::internal::Thread::CreateThreadLocalKey(); 574 Isolate::Current()->set_simulator_initialized(true);
577 initialized_ = true;
578 ::v8::internal::ExternalReference::set_redirector(&RedirectExternalReference); 575 ::v8::internal::ExternalReference::set_redirector(&RedirectExternalReference);
579 } 576 }
580 577
581 578
582 v8::internal::HashMap* Simulator::i_cache_ = NULL; 579 Simulator::Simulator() : isolate_(Isolate::Current()) {
583 580 i_cache_ = isolate_->simulator_i_cache();
584
585 Simulator::Simulator() {
586 if (i_cache_ == NULL) { 581 if (i_cache_ == NULL) {
587 i_cache_ = new v8::internal::HashMap(&ICacheMatch); 582 i_cache_ = new v8::internal::HashMap(&ICacheMatch);
583 isolate_->set_simulator_i_cache(i_cache_);
588 } 584 }
589 Initialize(); 585 Initialize();
590 // Setup simulator support first. Some of this information is needed to 586 // Setup simulator support first. Some of this information is needed to
591 // setup the architecture state. 587 // setup the architecture state.
592 size_t stack_size = 1 * 1024*1024; // allocate 1MB for stack 588 size_t stack_size = 1 * 1024*1024; // allocate 1MB for stack
593 stack_ = reinterpret_cast<char*>(malloc(stack_size)); 589 stack_ = reinterpret_cast<char*>(malloc(stack_size));
594 pc_modified_ = false; 590 pc_modified_ = false;
595 icount_ = 0; 591 icount_ = 0;
596 break_pc_ = NULL; 592 break_pc_ = NULL;
597 break_instr_ = 0; 593 break_instr_ = 0;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 // execute it with the simulator. We do that by redirecting the external 638 // execute it with the simulator. We do that by redirecting the external
643 // reference to a swi (software-interrupt) instruction that is handled by 639 // reference to a swi (software-interrupt) instruction that is handled by
644 // the simulator. We write the original destination of the jump just at a known 640 // the simulator. We write the original destination of the jump just at a known
645 // offset from the swi instruction so the simulator knows what to call. 641 // offset from the swi instruction so the simulator knows what to call.
646 class Redirection { 642 class Redirection {
647 public: 643 public:
648 Redirection(void* external_function, bool fp_return) 644 Redirection(void* external_function, bool fp_return)
649 : external_function_(external_function), 645 : external_function_(external_function),
650 swi_instruction_((AL << 28) | (0xf << 24) | call_rt_redirected), 646 swi_instruction_((AL << 28) | (0xf << 24) | call_rt_redirected),
651 fp_return_(fp_return), 647 fp_return_(fp_return),
652 next_(list_) { 648 next_(NULL) {
653 Simulator::current()-> 649 v8::internal::Isolate* isolate = Isolate::Current();
654 FlushICache(reinterpret_cast<void*>(&swi_instruction_), 650 next_ = isolate->simulator_redirection();
655 Instr::kInstrSize); 651 Simulator::FlushICache(isolate->simulator_i_cache(),
656 list_ = this; 652 reinterpret_cast<void*>(&swi_instruction_),
653 Instr::kInstrSize);
654 isolate->set_simulator_redirection(this);
657 } 655 }
658 656
659 void* address_of_swi_instruction() { 657 void* address_of_swi_instruction() {
660 return reinterpret_cast<void*>(&swi_instruction_); 658 return reinterpret_cast<void*>(&swi_instruction_);
661 } 659 }
662 660
663 void* external_function() { return external_function_; } 661 void* external_function() { return external_function_; }
664 bool fp_return() { return fp_return_; } 662 bool fp_return() { return fp_return_; }
665 663
666 static Redirection* Get(void* external_function, bool fp_return) { 664 static Redirection* Get(void* external_function, bool fp_return) {
667 Redirection* current; 665 Isolate* isolate = Isolate::Current();
668 for (current = list_; current != NULL; current = current->next_) { 666 Redirection* current = isolate->simulator_redirection();
667 for (; current != NULL; current = current->next_) {
669 if (current->external_function_ == external_function) return current; 668 if (current->external_function_ == external_function) return current;
670 } 669 }
671 return new Redirection(external_function, fp_return); 670 return new Redirection(external_function, fp_return);
672 } 671 }
673 672
674 static Redirection* FromSwiInstruction(Instr* swi_instruction) { 673 static Redirection* FromSwiInstruction(Instr* swi_instruction) {
675 char* addr_of_swi = reinterpret_cast<char*>(swi_instruction); 674 char* addr_of_swi = reinterpret_cast<char*>(swi_instruction);
676 char* addr_of_redirection = 675 char* addr_of_redirection =
677 addr_of_swi - OFFSET_OF(Redirection, swi_instruction_); 676 addr_of_swi - OFFSET_OF(Redirection, swi_instruction_);
678 return reinterpret_cast<Redirection*>(addr_of_redirection); 677 return reinterpret_cast<Redirection*>(addr_of_redirection);
679 } 678 }
680 679
681 private: 680 private:
682 void* external_function_; 681 void* external_function_;
683 uint32_t swi_instruction_; 682 uint32_t swi_instruction_;
684 bool fp_return_; 683 bool fp_return_;
685 Redirection* next_; 684 Redirection* next_;
686 static Redirection* list_;
687 }; 685 };
688 686
689 687
690 Redirection* Redirection::list_ = NULL;
691
692
693 void* Simulator::RedirectExternalReference(void* external_function, 688 void* Simulator::RedirectExternalReference(void* external_function,
694 bool fp_return) { 689 bool fp_return) {
695 Redirection* redirection = Redirection::Get(external_function, fp_return); 690 Redirection* redirection = Redirection::Get(external_function, fp_return);
696 return redirection->address_of_swi_instruction(); 691 return redirection->address_of_swi_instruction();
697 } 692 }
698 693
699 694
700 // Get the active Simulator for the current thread. 695 // Get the active Simulator for the current thread.
701 Simulator* Simulator::current() { 696 Simulator* Simulator::current(Isolate* isolate) {
697 v8::internal::Thread::LocalStorageKey* simulator_key =
698 Isolate::Current()->simulator_key();
702 Initialize(); 699 Initialize();
703 Simulator* sim = reinterpret_cast<Simulator*>( 700 Simulator* sim = reinterpret_cast<Simulator*>(
704 v8::internal::Thread::GetThreadLocal(simulator_key)); 701 v8::internal::Thread::GetThreadLocal(*simulator_key));
705 if (sim == NULL) { 702 if (sim == NULL) {
706 // TODO(146): delete the simulator object when a thread goes away. 703 // TODO(146): delete the simulator object when a thread goes away.
707 sim = new Simulator(); 704 sim = new Simulator();
708 v8::internal::Thread::SetThreadLocal(simulator_key, sim); 705 v8::internal::Thread::SetThreadLocal(*simulator_key, sim);
709 } 706 }
710 return sim; 707 return sim;
711 } 708 }
712 709
713 710
714 // Sets the register in the architecture state. It will also deal with updating 711 // Sets the register in the architecture state. It will also deal with updating
715 // Simulator internal state for special registers such as PC. 712 // Simulator internal state for special registers such as PC.
716 void Simulator::set_register(int reg, int32_t value) { 713 void Simulator::set_register(int reg, int32_t value) {
717 ASSERT((reg >= 0) && (reg < num_registers)); 714 ASSERT((reg >= 0) && (reg < num_registers));
718 if (reg == pc) { 715 if (reg == pc) {
(...skipping 1842 matching lines...) Expand 10 before | Expand all | Expand 10 after
2561 } 2558 }
2562 } else { 2559 } else {
2563 UNIMPLEMENTED(); // Not used by V8. 2560 UNIMPLEMENTED(); // Not used by V8.
2564 } 2561 }
2565 } 2562 }
2566 2563
2567 2564
2568 // Executes the current instruction. 2565 // Executes the current instruction.
2569 void Simulator::InstructionDecode(Instr* instr) { 2566 void Simulator::InstructionDecode(Instr* instr) {
2570 if (v8::internal::FLAG_check_icache) { 2567 if (v8::internal::FLAG_check_icache) {
2571 CheckICache(instr); 2568 CheckICache(isolate_->simulator_i_cache(), instr);
2572 } 2569 }
2573 pc_modified_ = false; 2570 pc_modified_ = false;
2574 if (::v8::internal::FLAG_trace_sim) { 2571 if (::v8::internal::FLAG_trace_sim) {
2575 disasm::NameConverter converter; 2572 disasm::NameConverter converter;
2576 disasm::Disassembler dasm(converter); 2573 disasm::Disassembler dasm(converter);
2577 // use a reasonably large buffer 2574 // use a reasonably large buffer
2578 v8::internal::EmbeddedVector<char, 256> buffer; 2575 v8::internal::EmbeddedVector<char, 256> buffer;
2579 dasm.InstructionDecode(buffer, 2576 dasm.InstructionDecode(buffer,
2580 reinterpret_cast<byte*>(instr)); 2577 reinterpret_cast<byte*>(instr));
2581 PrintF(" 0x%08x %s\n", instr, buffer.start()); 2578 PrintF(" 0x%08x %s\n", instr, buffer.start());
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
2762 uintptr_t address = *stack_slot; 2759 uintptr_t address = *stack_slot;
2763 set_register(sp, current_sp + sizeof(uintptr_t)); 2760 set_register(sp, current_sp + sizeof(uintptr_t));
2764 return address; 2761 return address;
2765 } 2762 }
2766 2763
2767 } } // namespace assembler::arm 2764 } } // namespace assembler::arm
2768 2765
2769 #endif // __arm__ 2766 #endif // __arm__
2770 2767
2771 #endif // V8_TARGET_ARCH_ARM 2768 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/simulator-arm.h ('k') | src/conversions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698