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

Side by Side Diff: src/ast-string-table.cc

Issue 231073002: WIP: Parser: delay string internalization. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: more cleanup Created 6 years, 6 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/ast-string-table.h ('k') | src/compiler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 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 "ast-string-table.h"
29
30 #include "api.h"
31 #include "objects.h"
32
33 namespace v8 {
34 namespace internal {
35
36 namespace {
37
38 template <typename Char>
39 int vector_hash(Vector<const Char> string) {
40 int hash = 0;
41 for (int i = 0; i < string.length(); i++) {
42 int c = static_cast<int>(string[i]);
43 hash += c;
44 hash += (hash << 10);
45 hash ^= (hash >> 6);
46 }
47 return hash;
48 }
49
50
51 // For using StringToArrayIndex.
52 class OneByteStringStream {
53 public:
54 explicit OneByteStringStream(Vector<const byte> lb) :
55 literal_bytes_(lb), pos_(0) {}
56
57 bool HasMore() { return pos_ < literal_bytes_.length(); }
58 uint16_t GetNext() { return literal_bytes_[pos_++]; }
59
60 private:
61 Vector<const byte> literal_bytes_;
62 int pos_;
63 };
64
65 }
66
67
68 bool AstString::AsArrayIndex(uint32_t* index) const {
69 if (!string_.is_null())
70 return string_->AsArrayIndex(index);
71 if (!is_one_byte_) return false;
72 if (literal_bytes_.length() == 0 ||
73 literal_bytes_.length() > String::kMaxArrayIndexSize)
74 return false;
75 OneByteStringStream stream(literal_bytes_);
76 return StringToArrayIndex(&stream, index);
77 }
78
79
80 bool AstString::IsOneByteEqualTo(const char* data) const {
81 int length = strlen(data);
82 if (is_one_byte_ && literal_bytes_.length() == length) {
83 const char* token = reinterpret_cast<const char*>(literal_bytes_.start());
84 return !strncmp(token, data, length);
85 }
86 return false;
87 }
88
89
90 void AstString::Internalize(Isolate* isolate) {
91 if (!string_.is_null()) return;
92 if (literal_bytes_.length() == 0) {
93 string_ = isolate->factory()->empty_string();
94 } else if (is_one_byte_) {
95 string_ = isolate->factory()->InternalizeOneByteString(literal_bytes_);
96 } else {
97 string_ = isolate->factory()->InternalizeTwoByteString(
98 Vector<const uint16_t>::cast(literal_bytes_));
99 }
100 }
101
102
103 bool AstString::Compare(void* a, void* b) {
104 AstString* string1 = reinterpret_cast<AstString*>(a);
105 AstString* string2 = reinterpret_cast<AstString*>(b);
106 if (string1->is_one_byte_ != string2->is_one_byte_) return false;
107 if (string1->hash_ != string2->hash_) return false;
108 int length = string1->literal_bytes_.length();
109 if (string2->literal_bytes_.length() != length) return false;
110 return memcmp(string1->literal_bytes_.start(),
111 string2->literal_bytes_.start(), length) == 0;
112 }
113
114
115 bool AstValue::IsPropertyName() const {
116 if (type_ == STRING) {
117 uint32_t index;
118 return !string_->AsArrayIndex(&index);
119 }
120 return false;
121 }
122
123
124 bool AstValue::BooleanValue() const {
125 switch (type_) {
126 case STRING:
127 ASSERT(string_ != NULL);
128 return string_->length() != 0;
129 case NUMBER:
130 return DoubleToBoolean(number_);
131 case SMI:
132 return smi_ != 0;
133 case STRING_ARRAY:
134 UNREACHABLE();
135 break;
136 case BOOLEAN:
137 return bool_;
138 case NULL_TYPE:
139 return false;
140 case THE_HOLE:
141 UNREACHABLE();
142 break;
143 case UNDEFINED:
144 return false;
145 default:
146 UNREACHABLE();
147 break;
148 }
149 return false;
150 }
151
152
153 void AstValue::Internalize(Isolate* isolate) {
154 switch (type_) {
155 case STRING:
156 ASSERT(string_ != NULL);
157 // Strings are already internalized.
158 ASSERT(!string_->string().is_null());
159 break;
160 case NUMBER:
161 value_ = isolate->factory()->NewNumber(number_, TENURED);
162 break;
163 case SMI:
164 value_ = handle(Smi::FromInt(smi_), isolate);
165 break;
166 case BOOLEAN:
167 if (bool_) {
168 value_ = isolate->factory()->true_value();
169 } else {
170 value_ = isolate->factory()->false_value();
171 }
172 break;
173 case STRING_ARRAY: {
174 ASSERT(strings_ != NULL);
175 Factory* factory = isolate->factory();
176 int len = strings_->length();
177 Handle<FixedArray> elements = factory->NewFixedArray(len, TENURED);
178 for (int i = 0; i < len; i++) {
179 const AstString* string = (*strings_)[i];
180 Handle<Object> element = string->string();
181 // Strings are already internalized.
182 ASSERT(!element.is_null());
183 elements->set(i, *element);
184 }
185 value_ =
186 factory->NewJSArrayWithElements(elements, FAST_ELEMENTS, TENURED);
187 break;
188 }
189 case NULL_TYPE:
190 value_ = isolate->factory()->null_value();
191 break;
192 case THE_HOLE:
193 value_ = isolate->factory()->the_hole_value();
194 break;
195 case UNDEFINED:
196 value_ = isolate->factory()->undefined_value();
197 break;
198 default:
199 UNREACHABLE();
200 break;
201 }
202 }
203
204
205 const AstString* AstStringTable::GetOneByteString(
206 Vector<const uint8_t> literal) {
207 return GetString(vector_hash(literal), true, literal);
208 }
209
210
211 const AstString* AstStringTable::GetTwoByteString(
212 Vector<const uint16_t> literal) {
213 return GetString(vector_hash(literal), false,
214 Vector<const byte>::cast(literal));
215 }
216
217
218 const AstString* AstStringTable::GetString(Handle<String> literal) {
219 DisallowHeapAllocation no_gc;
220 String::FlatContent content = literal->GetFlatContent();
221 if (content.IsAscii()) {
222 return GetOneByteString(content.ToOneByteVector());
223 }
224 ASSERT(content.IsTwoByte());
225 return GetTwoByteString(content.ToUC16Vector());
226 }
227
228
229 void AstStringTable::Internalize(Isolate* isolate) {
230 if (isolate_) {
231 // Everything is already internalized.
232 return;
233 }
234 // Strings need to be internalized before values, because values refer to
235 // strings.
236 for (HashMap::Entry* p = string_table_.Start(); p != NULL;
237 p = string_table_.Next(p)) {
238 AstString* string = reinterpret_cast<AstString*>(p->key);
239 string->Internalize(isolate);
240 }
241 for (int i = 0; i < values_.length(); ++i) {
242 values_[i]->Internalize(isolate);
243 }
244 isolate_ = isolate;
245 }
246
247
248 const AstValue* AstStringTable::NewValue(const AstString* string) {
249 AstValue* value = new (zone_) AstValue(string);
250 ASSERT(string != NULL);
251 if (isolate_) {
252 value->Internalize(isolate_);
253 }
254 values_.Add(value);
255 return value;
256 }
257
258
259 const AstValue* AstStringTable::NewNumberValue(double number) {
260 AstValue* value = new (zone_) AstValue(number);
261 if (isolate_) {
262 value->Internalize(isolate_);
263 }
264 values_.Add(value);
265 return value;
266 }
267
268
269 const AstValue* AstStringTable::NewSmiValue(int number) {
270 AstValue* value =
271 new (zone_) AstValue(AstValue::SMI, number);
272 if (isolate_) {
273 value->Internalize(isolate_);
274 }
275 values_.Add(value);
276 return value;
277 }
278
279
280 const AstValue* AstStringTable::NewValue(bool b) {
281 AstValue* value = new (zone_) AstValue(b);
282 if (isolate_) {
283 value->Internalize(isolate_);
284 }
285 values_.Add(value);
286 return value;
287 }
288
289
290 const AstValue* AstStringTable::NewValue(ZoneList<const AstString*>* strings) {
291 AstValue* value = new (zone_) AstValue(strings);
292 if (isolate_) {
293 value->Internalize(isolate_);
294 }
295 values_.Add(value);
296 return value;
297 }
298
299
300 const AstValue* AstStringTable::NewValue(AstValue::Type t) {
301 ASSERT(t == AstValue::NULL_TYPE || t == AstValue::UNDEFINED ||
302 t == AstValue::THE_HOLE);
303 AstValue* value = new (zone_) AstValue(t);
304 if (isolate_) {
305 value->Internalize(isolate_);
306 }
307 values_.Add(value);
308 return value;
309 }
310
311
312 const AstString* AstStringTable::GetString(int hash, bool is_one_byte,
313 Vector<const byte> literal_bytes) {
314 // literal_bytes here points to whatever the user passed, and this is OK
315 // because we use vector_compare (which checks the contents) to compare
316 // against the AstStrings which are in the string_table_. We should not return
317 // this AstString.
318 AstString key(is_one_byte, literal_bytes, hash);
319 HashMap::Entry* entry = string_table_.Lookup(&key, hash, true);
320 if (entry->value == NULL) {
321 // Copy literal contents for later comparison.
322 key.literal_bytes_ =
323 Vector<const byte>::cast(literal_chars_.AddBlock(literal_bytes));
324 // This Vector will be valid as long as the Collector is alive (meaning that
325 // the AstString will not be moved).
326 Vector<AstString> new_string = string_table_keys_.AddBlock(1, key);
327 entry->key = &new_string[0];
328 if (isolate_) {
329 new_string[0].Internalize(isolate_);
330 }
331 entry->value = reinterpret_cast<void*>(1);
332 }
333 return reinterpret_cast<AstString*>(entry->key);
334 }
335
336
337 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ast-string-table.h ('k') | src/compiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698