1 // Copyright 2011 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 #include "src/assembler.h" 29 #include "src/macro-assembler.h" 30 #include "test/cctest/cctest.h" 31 32 namespace v8 { 33 namespace internal { 34 35 static void WriteRinfo(RelocInfoWriter* writer, 36 byte* pc, RelocInfo::Mode mode, intptr_t data) { 37 RelocInfo rinfo(CcTest::i_isolate(), pc, mode, data, NULL); 38 writer->Write(&rinfo); 39 } 40 41 42 // Tests that writing both types of positions and then reading either 43 // or both works as expected. 44 TEST(Positions) { 45 CcTest::InitializeVM(); 46 const int code_size = 10 * KB; 47 int relocation_info_size = 10 * KB; 48 const int buffer_size = code_size + relocation_info_size; 49 v8::base::SmartArrayPointer<byte> buffer(new byte[buffer_size]); 50 51 byte* pc = buffer.get(); 52 byte* buffer_end = buffer.get() + buffer_size; 53 54 RelocInfoWriter writer(buffer_end, pc); 55 byte* relocation_info_end = buffer_end - relocation_info_size; 56 for (int i = 0, pos = 0; i < 100; i++, pc += i, pos += i) { 57 RelocInfo::Mode mode = (i % 2 == 0) ? 58 RelocInfo::STATEMENT_POSITION : RelocInfo::POSITION; 59 if (mode == RelocInfo::STATEMENT_POSITION) { 60 printf("TEST WRITING STATEMENT %p %d\n", pc, pos); 61 } else { 62 printf("TEST WRITING POSITION %p %d\n", pc, pos); 63 } 64 WriteRinfo(&writer, pc, mode, pos); 65 CHECK(writer.pos() - RelocInfoWriter::kMaxSize >= relocation_info_end); 66 } 67 68 writer.Finish(); 69 relocation_info_size = static_cast<int>(buffer_end - writer.pos()); 70 MacroAssembler assm(CcTest::i_isolate(), nullptr, 0, CodeObjectRequired::kNo); 71 CodeDesc desc = {buffer.get(), buffer_size, code_size, 72 relocation_info_size, 0, &assm}; 73 74 // Read only (non-statement) positions. 75 { 76 RelocIterator it(desc, RelocInfo::ModeMask(RelocInfo::POSITION)); 77 pc = buffer.get(); 78 for (int i = 0, pos = 0; i < 100; i++, pc += i, pos += i) { 79 printf("TESTING 1: %d\n", i); 80 RelocInfo::Mode mode = (i % 2 == 0) ? 81 RelocInfo::STATEMENT_POSITION : RelocInfo::POSITION; 82 if (mode == RelocInfo::POSITION) { 83 CHECK_EQ(pc, it.rinfo()->pc()); 84 CHECK_EQ(mode, it.rinfo()->rmode()); 85 CHECK_EQ(pos, static_cast<int>(it.rinfo()->data())); 86 it.next(); 87 } 88 } 89 CHECK(it.done()); 90 } 91 92 // Read only statement positions. 93 { 94 RelocIterator it(desc, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION)); 95 pc = buffer.get(); 96 for (int i = 0, pos = 0; i < 100; i++, pc += i, pos += i) { 97 RelocInfo::Mode mode = (i % 2 == 0) ? 98 RelocInfo::STATEMENT_POSITION : RelocInfo::POSITION; 99 if (mode == RelocInfo::STATEMENT_POSITION) { 100 CHECK_EQ(pc, it.rinfo()->pc()); 101 CHECK_EQ(mode, it.rinfo()->rmode()); 102 CHECK_EQ(pos, static_cast<int>(it.rinfo()->data())); 103 it.next(); 104 } 105 } 106 CHECK(it.done()); 107 } 108 109 // Read both types of positions. 110 { 111 RelocIterator it(desc, RelocInfo::kPositionMask); 112 pc = buffer.get(); 113 for (int i = 0, pos = 0; i < 100; i++, pc += i, pos += i) { 114 RelocInfo::Mode mode = (i % 2 == 0) ? 115 RelocInfo::STATEMENT_POSITION : RelocInfo::POSITION; 116 CHECK_EQ(pc, it.rinfo()->pc()); 117 CHECK_EQ(mode, it.rinfo()->rmode()); 118 CHECK_EQ(pos, static_cast<int>(it.rinfo()->data())); 119 it.next(); 120 } 121 CHECK(it.done()); 122 } 123 } 124 125 } // namespace internal 126 } // namespace v8 127