| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "../include/v8stdint.h" | 5 #include "../include/v8stdint.h" |
| 6 | 6 |
| 7 #include "preparse-data-format.h" | 7 #include "preparse-data-format.h" |
| 8 #include "preparse-data.h" | 8 #include "preparse-data.h" |
| 9 | 9 |
| 10 #include "checks.h" | 10 #include "checks.h" |
| 11 #include "globals.h" | 11 #include "globals.h" |
| 12 #include "hashmap.h" | 12 #include "hashmap.h" |
| 13 | 13 |
| 14 namespace v8 { | 14 namespace v8 { |
| 15 namespace internal { | 15 namespace internal { |
| 16 | 16 |
| 17 | 17 |
| 18 template <typename Char> | |
| 19 static int vector_hash(Vector<const Char> string) { | |
| 20 int hash = 0; | |
| 21 for (int i = 0; i < string.length(); i++) { | |
| 22 int c = static_cast<int>(string[i]); | |
| 23 hash += c; | |
| 24 hash += (hash << 10); | |
| 25 hash ^= (hash >> 6); | |
| 26 } | |
| 27 return hash; | |
| 28 } | |
| 29 | |
| 30 | |
| 31 static bool vector_compare(void* a, void* b) { | |
| 32 CompleteParserRecorder::Key* string1 = | |
| 33 reinterpret_cast<CompleteParserRecorder::Key*>(a); | |
| 34 CompleteParserRecorder::Key* string2 = | |
| 35 reinterpret_cast<CompleteParserRecorder::Key*>(b); | |
| 36 if (string1->is_one_byte != string2->is_one_byte) return false; | |
| 37 int length = string1->literal_bytes.length(); | |
| 38 if (string2->literal_bytes.length() != length) return false; | |
| 39 return memcmp(string1->literal_bytes.start(), | |
| 40 string2->literal_bytes.start(), length) == 0; | |
| 41 } | |
| 42 | |
| 43 | |
| 44 CompleteParserRecorder::CompleteParserRecorder() | 18 CompleteParserRecorder::CompleteParserRecorder() |
| 45 : function_store_(0), | 19 : function_store_(0) { |
| 46 literal_chars_(0), | |
| 47 symbol_store_(0), | |
| 48 symbol_keys_(0), | |
| 49 string_table_(vector_compare), | |
| 50 symbol_id_(0) { | |
| 51 preamble_[PreparseDataConstants::kMagicOffset] = | 20 preamble_[PreparseDataConstants::kMagicOffset] = |
| 52 PreparseDataConstants::kMagicNumber; | 21 PreparseDataConstants::kMagicNumber; |
| 53 preamble_[PreparseDataConstants::kVersionOffset] = | 22 preamble_[PreparseDataConstants::kVersionOffset] = |
| 54 PreparseDataConstants::kCurrentVersion; | 23 PreparseDataConstants::kCurrentVersion; |
| 55 preamble_[PreparseDataConstants::kHasErrorOffset] = false; | 24 preamble_[PreparseDataConstants::kHasErrorOffset] = false; |
| 56 preamble_[PreparseDataConstants::kFunctionsSizeOffset] = 0; | 25 preamble_[PreparseDataConstants::kFunctionsSizeOffset] = 0; |
| 57 preamble_[PreparseDataConstants::kSymbolCountOffset] = 0; | |
| 58 preamble_[PreparseDataConstants::kSizeOffset] = 0; | 26 preamble_[PreparseDataConstants::kSizeOffset] = 0; |
| 59 ASSERT_EQ(6, PreparseDataConstants::kHeaderSize); | 27 ASSERT_EQ(5, PreparseDataConstants::kHeaderSize); |
| 60 #ifdef DEBUG | 28 #ifdef DEBUG |
| 61 prev_start_ = -1; | 29 prev_start_ = -1; |
| 62 #endif | 30 #endif |
| 63 } | 31 } |
| 64 | 32 |
| 65 | 33 |
| 66 void CompleteParserRecorder::LogMessage(int start_pos, | 34 void CompleteParserRecorder::LogMessage(int start_pos, |
| 67 int end_pos, | 35 int end_pos, |
| 68 const char* message, | 36 const char* message, |
| 69 const char* arg_opt, | 37 const char* arg_opt, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 86 | 54 |
| 87 | 55 |
| 88 void CompleteParserRecorder::WriteString(Vector<const char> str) { | 56 void CompleteParserRecorder::WriteString(Vector<const char> str) { |
| 89 function_store_.Add(str.length()); | 57 function_store_.Add(str.length()); |
| 90 for (int i = 0; i < str.length(); i++) { | 58 for (int i = 0; i < str.length(); i++) { |
| 91 function_store_.Add(str[i]); | 59 function_store_.Add(str[i]); |
| 92 } | 60 } |
| 93 } | 61 } |
| 94 | 62 |
| 95 | 63 |
| 96 void CompleteParserRecorder::LogOneByteSymbol(int start, | |
| 97 Vector<const uint8_t> literal) { | |
| 98 int hash = vector_hash(literal); | |
| 99 LogSymbol(start, hash, true, literal); | |
| 100 } | |
| 101 | |
| 102 | |
| 103 void CompleteParserRecorder::LogTwoByteSymbol(int start, | |
| 104 Vector<const uint16_t> literal) { | |
| 105 int hash = vector_hash(literal); | |
| 106 LogSymbol(start, hash, false, Vector<const byte>::cast(literal)); | |
| 107 } | |
| 108 | |
| 109 | |
| 110 void CompleteParserRecorder::LogSymbol(int start, | |
| 111 int hash, | |
| 112 bool is_one_byte, | |
| 113 Vector<const byte> literal_bytes) { | |
| 114 Key key = { is_one_byte, literal_bytes }; | |
| 115 HashMap::Entry* entry = string_table_.Lookup(&key, hash, true); | |
| 116 int id = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); | |
| 117 if (id == 0) { | |
| 118 // Copy literal contents for later comparison. | |
| 119 key.literal_bytes = | |
| 120 Vector<const byte>::cast(literal_chars_.AddBlock(literal_bytes)); | |
| 121 // Put (symbol_id_ + 1) into entry and increment it. | |
| 122 id = ++symbol_id_; | |
| 123 entry->value = reinterpret_cast<void*>(id); | |
| 124 Vector<Key> symbol = symbol_keys_.AddBlock(1, key); | |
| 125 entry->key = &symbol[0]; | |
| 126 } | |
| 127 WriteNumber(id - 1); | |
| 128 } | |
| 129 | |
| 130 | |
| 131 Vector<unsigned> CompleteParserRecorder::ExtractData() { | 64 Vector<unsigned> CompleteParserRecorder::ExtractData() { |
| 132 int function_size = function_store_.size(); | 65 int function_size = function_store_.size(); |
| 133 // Add terminator to symbols, then pad to unsigned size. | 66 int total_size = PreparseDataConstants::kHeaderSize + function_size; |
| 134 int symbol_size = symbol_store_.size(); | |
| 135 int padding = sizeof(unsigned) - (symbol_size % sizeof(unsigned)); | |
| 136 symbol_store_.AddBlock(padding, PreparseDataConstants::kNumberTerminator); | |
| 137 symbol_size += padding; | |
| 138 int total_size = PreparseDataConstants::kHeaderSize + function_size | |
| 139 + (symbol_size / sizeof(unsigned)); | |
| 140 Vector<unsigned> data = Vector<unsigned>::New(total_size); | 67 Vector<unsigned> data = Vector<unsigned>::New(total_size); |
| 141 preamble_[PreparseDataConstants::kFunctionsSizeOffset] = function_size; | 68 preamble_[PreparseDataConstants::kFunctionsSizeOffset] = function_size; |
| 142 preamble_[PreparseDataConstants::kSymbolCountOffset] = symbol_id_; | |
| 143 OS::MemCopy(data.start(), preamble_, sizeof(preamble_)); | 69 OS::MemCopy(data.start(), preamble_, sizeof(preamble_)); |
| 144 int symbol_start = PreparseDataConstants::kHeaderSize + function_size; | |
| 145 if (function_size > 0) { | 70 if (function_size > 0) { |
| 146 function_store_.WriteTo(data.SubVector(PreparseDataConstants::kHeaderSize, | 71 function_store_.WriteTo(data.SubVector(PreparseDataConstants::kHeaderSize, |
| 147 symbol_start)); | 72 total_size)); |
| 148 } | |
| 149 if (!has_error()) { | |
| 150 symbol_store_.WriteTo( | |
| 151 Vector<byte>::cast(data.SubVector(symbol_start, total_size))); | |
| 152 } | 73 } |
| 153 return data; | 74 return data; |
| 154 } | 75 } |
| 155 | 76 |
| 156 | 77 |
| 157 void CompleteParserRecorder::WriteNumber(int number) { | |
| 158 // Split the number into chunks of 7 bits. Write them one after another (the | |
| 159 // most significant first). Use the MSB of each byte for signalling that the | |
| 160 // number continues. See ScriptDataImpl::ReadNumber for the reading side. | |
| 161 ASSERT(number >= 0); | |
| 162 | |
| 163 int mask = (1 << 28) - 1; | |
| 164 int i = 28; | |
| 165 // 26 million symbols ought to be enough for anybody. | |
| 166 ASSERT(number <= mask); | |
| 167 while (number < mask) { | |
| 168 mask >>= 7; | |
| 169 i -= 7; | |
| 170 } | |
| 171 while (i > 0) { | |
| 172 symbol_store_.Add(static_cast<byte>(number >> i) | 0x80u); | |
| 173 number &= mask; | |
| 174 mask >>= 7; | |
| 175 i -= 7; | |
| 176 } | |
| 177 ASSERT(number < (1 << 7)); | |
| 178 symbol_store_.Add(static_cast<byte>(number)); | |
| 179 } | |
| 180 | |
| 181 | |
| 182 } } // namespace v8::internal. | 78 } } // namespace v8::internal. |
| OLD | NEW |