OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 // Consider sorting them according to type as well? | 44 // Consider sorting them according to type as well? |
45 return x - y; | 45 return x - y; |
46 } | 46 } |
47 | 47 |
48 | 48 |
49 template<class Allocator> | 49 template<class Allocator> |
50 ScopeInfo<Allocator>::ScopeInfo(Scope* scope) | 50 ScopeInfo<Allocator>::ScopeInfo(Scope* scope) |
51 : function_name_(FACTORY->empty_symbol()), | 51 : function_name_(FACTORY->empty_symbol()), |
52 calls_eval_(scope->calls_eval()), | 52 calls_eval_(scope->calls_eval()), |
53 is_strict_mode_(scope->is_strict_mode()), | 53 is_strict_mode_(scope->is_strict_mode()), |
| 54 type_(scope->type()), |
54 parameters_(scope->num_parameters()), | 55 parameters_(scope->num_parameters()), |
55 stack_slots_(scope->num_stack_slots()), | 56 stack_slots_(scope->num_stack_slots()), |
56 context_slots_(scope->num_heap_slots()), | 57 context_slots_(scope->num_heap_slots()), |
57 context_modes_(scope->num_heap_slots()) { | 58 context_modes_(scope->num_heap_slots()) { |
58 // Add parameters. | 59 // Add parameters. |
59 for (int i = 0; i < scope->num_parameters(); i++) { | 60 for (int i = 0; i < scope->num_parameters(); i++) { |
60 ASSERT(parameters_.length() == i); | 61 ASSERT(parameters_.length() == i); |
61 parameters_.Add(scope->parameter(i)->name()); | 62 parameters_.Add(scope->parameter(i)->name()); |
62 } | 63 } |
63 | 64 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 } | 144 } |
144 } | 145 } |
145 | 146 |
146 | 147 |
147 // Encoding format in a FixedArray object: | 148 // Encoding format in a FixedArray object: |
148 // | 149 // |
149 // - function name | 150 // - function name |
150 // | 151 // |
151 // - calls eval boolean flag | 152 // - calls eval boolean flag |
152 // | 153 // |
| 154 // - is strict mode scope |
| 155 // |
| 156 // - scope type |
| 157 // |
153 // - number of variables in the context object (smi) (= function context | 158 // - number of variables in the context object (smi) (= function context |
154 // slot index + 1) | 159 // slot index + 1) |
155 // - list of pairs (name, Var mode) of context-allocated variables (starting | 160 // - list of pairs (name, Var mode) of context-allocated variables (starting |
156 // with context slot 0) | 161 // with context slot 0) |
157 // | 162 // |
158 // - number of parameters (smi) | 163 // - number of parameters (smi) |
159 // - list of parameter names (starting with parameter 0 first) | 164 // - list of parameter names (starting with parameter 0 first) |
160 // | 165 // |
161 // - number of variables on the stack (smi) | 166 // - number of variables on the stack (smi) |
162 // - list of names of stack-allocated variables (starting with stack slot 0) | 167 // - list of names of stack-allocated variables (starting with stack slot 0) |
(...skipping 11 matching lines...) Expand all Loading... |
174 // subsequent list | 179 // subsequent list |
175 // - the list entries don't have to be in any particular order, so all the | 180 // - the list entries don't have to be in any particular order, so all the |
176 // current sorting business can go away | 181 // current sorting business can go away |
177 // - the ScopeInfo lookup routines can be reduced to perhaps a single lookup | 182 // - the ScopeInfo lookup routines can be reduced to perhaps a single lookup |
178 // which returns all information at once | 183 // which returns all information at once |
179 // - when gathering the information from a Scope, we only need to iterate | 184 // - when gathering the information from a Scope, we only need to iterate |
180 // through the local variables (parameters and context info is already | 185 // through the local variables (parameters and context info is already |
181 // present) | 186 // present) |
182 | 187 |
183 | 188 |
184 static inline Object** ReadInt(Object** p, int* x) { | 189 template <class T> |
185 *x = (reinterpret_cast<Smi*>(*p++))->value(); | 190 static inline Object** ReadInt(Object** p, T* x) { |
| 191 *x = static_cast<T>((reinterpret_cast<Smi*>(*p++))->value()); |
186 return p; | 192 return p; |
187 } | 193 } |
188 | 194 |
189 | 195 |
190 static inline Object** ReadBool(Object** p, bool* x) { | 196 static inline Object** ReadBool(Object** p, bool* x) { |
191 *x = (reinterpret_cast<Smi*>(*p++))->value() != 0; | 197 *x = (reinterpret_cast<Smi*>(*p++))->value() != 0; |
192 return p; | 198 return p; |
193 } | 199 } |
194 | 200 |
195 | 201 |
196 static inline Object** ReadSymbol(Object** p, Handle<String>* s) { | 202 template <class T> |
197 *s = Handle<String>(reinterpret_cast<String*>(*p++)); | 203 static inline Object** ReadObject(Object** p, Handle<T>* s) { |
| 204 *s = Handle<T>::cast(Handle<Object>(*p++)); |
198 return p; | 205 return p; |
199 } | 206 } |
200 | 207 |
201 | 208 |
202 template <class Allocator> | 209 template <class Allocator, class T> |
203 static Object** ReadList(Object** p, List<Handle<String>, Allocator >* list) { | 210 static Object** ReadList(Object** p, List<Handle<T>, Allocator >* list) { |
204 ASSERT(list->is_empty()); | 211 ASSERT(list->is_empty()); |
205 int n; | 212 int n; |
206 p = ReadInt(p, &n); | 213 p = ReadInt(p, &n); |
207 while (n-- > 0) { | 214 while (n-- > 0) { |
208 Handle<String> s; | 215 Handle<T> s; |
209 p = ReadSymbol(p, &s); | 216 p = ReadObject(p, &s); |
210 list->Add(s); | 217 list->Add(s); |
211 } | 218 } |
212 return p; | 219 return p; |
213 } | 220 } |
214 | 221 |
215 | 222 |
216 template <class Allocator> | 223 template <class Allocator> |
217 static Object** ReadList(Object** p, | 224 static Object** ReadList(Object** p, |
218 List<Handle<String>, Allocator>* list, | 225 List<Handle<String>, Allocator>* list, |
219 List<VariableMode, Allocator>* modes) { | 226 List<VariableMode, Allocator>* modes) { |
220 ASSERT(list->is_empty()); | 227 ASSERT(list->is_empty()); |
221 int n; | 228 int n; |
222 p = ReadInt(p, &n); | 229 p = ReadInt(p, &n); |
223 while (n-- > 0) { | 230 while (n-- > 0) { |
224 Handle<String> s; | 231 Handle<String> s; |
225 int m; | 232 int m; |
226 p = ReadSymbol(p, &s); | 233 p = ReadObject(p, &s); |
227 p = ReadInt(p, &m); | 234 p = ReadInt(p, &m); |
228 list->Add(s); | 235 list->Add(s); |
229 modes->Add(static_cast<VariableMode>(m)); | 236 modes->Add(static_cast<VariableMode>(m)); |
230 } | 237 } |
231 return p; | 238 return p; |
232 } | 239 } |
233 | 240 |
234 | 241 |
235 template<class Allocator> | 242 template<class Allocator> |
236 ScopeInfo<Allocator>::ScopeInfo(SerializedScopeInfo* data) | 243 ScopeInfo<Allocator>::ScopeInfo(SerializedScopeInfo* data) |
237 : function_name_(FACTORY->empty_symbol()), | 244 : function_name_(FACTORY->empty_symbol()), |
238 parameters_(4), | 245 parameters_(4), |
239 stack_slots_(8), | 246 stack_slots_(8), |
240 context_slots_(8), | 247 context_slots_(8), |
241 context_modes_(8) { | 248 context_modes_(8) { |
242 if (data->length() > 0) { | 249 if (data->length() > 0) { |
243 Object** p0 = data->data_start(); | 250 Object** p0 = data->data_start(); |
244 Object** p = p0; | 251 Object** p = p0; |
245 p = ReadSymbol(p, &function_name_); | 252 p = ReadObject(p, &function_name_); |
246 p = ReadBool(p, &calls_eval_); | 253 p = ReadBool(p, &calls_eval_); |
247 p = ReadBool(p, &is_strict_mode_); | 254 p = ReadBool(p, &is_strict_mode_); |
| 255 p = ReadInt(p, &type_); |
248 p = ReadList<Allocator>(p, &context_slots_, &context_modes_); | 256 p = ReadList<Allocator>(p, &context_slots_, &context_modes_); |
249 p = ReadList<Allocator>(p, ¶meters_); | 257 p = ReadList<Allocator>(p, ¶meters_); |
250 p = ReadList<Allocator>(p, &stack_slots_); | 258 p = ReadList<Allocator>(p, &stack_slots_); |
251 ASSERT((p - p0) == FixedArray::cast(data)->length()); | 259 ASSERT((p - p0) == FixedArray::cast(data)->length()); |
252 } | 260 } |
253 } | 261 } |
254 | 262 |
255 | 263 |
256 static inline Object** WriteInt(Object** p, int x) { | 264 static inline Object** WriteInt(Object** p, int x) { |
257 *p++ = Smi::FromInt(x); | 265 *p++ = Smi::FromInt(x); |
258 return p; | 266 return p; |
259 } | 267 } |
260 | 268 |
261 | 269 |
262 static inline Object** WriteBool(Object** p, bool b) { | 270 static inline Object** WriteBool(Object** p, bool b) { |
263 *p++ = Smi::FromInt(b ? 1 : 0); | 271 *p++ = Smi::FromInt(b ? 1 : 0); |
264 return p; | 272 return p; |
265 } | 273 } |
266 | 274 |
267 | 275 |
268 static inline Object** WriteSymbol(Object** p, Handle<String> s) { | 276 template <class T> |
| 277 static inline Object** WriteObject(Object** p, Handle<T> s) { |
269 *p++ = *s; | 278 *p++ = *s; |
270 return p; | 279 return p; |
271 } | 280 } |
272 | 281 |
273 | 282 |
274 template <class Allocator> | 283 template <class Allocator, class T> |
275 static Object** WriteList(Object** p, List<Handle<String>, Allocator >* list) { | 284 static Object** WriteList(Object** p, List<Handle<T>, Allocator >* list) { |
276 const int n = list->length(); | 285 const int n = list->length(); |
277 p = WriteInt(p, n); | 286 p = WriteInt(p, n); |
278 for (int i = 0; i < n; i++) { | 287 for (int i = 0; i < n; i++) { |
279 p = WriteSymbol(p, list->at(i)); | 288 p = WriteObject(p, list->at(i)); |
280 } | 289 } |
281 return p; | 290 return p; |
282 } | 291 } |
283 | 292 |
284 | 293 |
285 template <class Allocator> | 294 template <class Allocator> |
286 static Object** WriteList(Object** p, | 295 static Object** WriteList(Object** p, |
287 List<Handle<String>, Allocator>* list, | 296 List<Handle<String>, Allocator>* list, |
288 List<VariableMode, Allocator>* modes) { | 297 List<VariableMode, Allocator>* modes) { |
289 const int n = list->length(); | 298 const int n = list->length(); |
290 p = WriteInt(p, n); | 299 p = WriteInt(p, n); |
291 for (int i = 0; i < n; i++) { | 300 for (int i = 0; i < n; i++) { |
292 p = WriteSymbol(p, list->at(i)); | 301 p = WriteObject(p, list->at(i)); |
293 p = WriteInt(p, modes->at(i)); | 302 p = WriteInt(p, modes->at(i)); |
294 } | 303 } |
295 return p; | 304 return p; |
296 } | 305 } |
297 | 306 |
298 | 307 |
299 template<class Allocator> | 308 template<class Allocator> |
300 Handle<SerializedScopeInfo> ScopeInfo<Allocator>::Serialize() { | 309 Handle<SerializedScopeInfo> ScopeInfo<Allocator>::Serialize() { |
301 // function name, calls eval, is_strict_mode, length for 3 tables: | 310 // function name, calls eval, is_strict_mode, scope type, |
302 const int extra_slots = 1 + 1 + 1 + 3; | 311 // length for 3 tables: |
| 312 const int extra_slots = 1 + 1 + 1 + 1 + 3; |
303 int length = extra_slots + | 313 int length = extra_slots + |
304 context_slots_.length() * 2 + | 314 context_slots_.length() * 2 + |
305 parameters_.length() + | 315 parameters_.length() + |
306 stack_slots_.length(); | 316 stack_slots_.length(); |
307 | 317 |
308 Handle<SerializedScopeInfo> data( | 318 Handle<SerializedScopeInfo> data( |
309 SerializedScopeInfo::cast(*FACTORY->NewSerializedScopeInfo(length))); | 319 SerializedScopeInfo::cast(*FACTORY->NewSerializedScopeInfo(length))); |
310 AssertNoAllocation nogc; | 320 AssertNoAllocation nogc; |
311 | 321 |
312 Object** p0 = data->data_start(); | 322 Object** p0 = data->data_start(); |
313 Object** p = p0; | 323 Object** p = p0; |
314 p = WriteSymbol(p, function_name_); | 324 p = WriteObject(p, function_name_); |
315 p = WriteBool(p, calls_eval_); | 325 p = WriteBool(p, calls_eval_); |
316 p = WriteBool(p, is_strict_mode_); | 326 p = WriteBool(p, is_strict_mode_); |
| 327 p = WriteInt(p, type_); |
317 p = WriteList(p, &context_slots_, &context_modes_); | 328 p = WriteList(p, &context_slots_, &context_modes_); |
318 p = WriteList(p, ¶meters_); | 329 p = WriteList(p, ¶meters_); |
319 p = WriteList(p, &stack_slots_); | 330 p = WriteList(p, &stack_slots_); |
320 ASSERT((p - p0) == length); | 331 ASSERT((p - p0) == length); |
321 | 332 |
322 return data; | 333 return data; |
323 } | 334 } |
324 | 335 |
325 | 336 |
326 template<class Allocator> | 337 template<class Allocator> |
(...skipping 27 matching lines...) Expand all Loading... |
354 } | 365 } |
355 | 366 |
356 | 367 |
357 SerializedScopeInfo* SerializedScopeInfo::Empty() { | 368 SerializedScopeInfo* SerializedScopeInfo::Empty() { |
358 return reinterpret_cast<SerializedScopeInfo*>(HEAP->empty_fixed_array()); | 369 return reinterpret_cast<SerializedScopeInfo*>(HEAP->empty_fixed_array()); |
359 } | 370 } |
360 | 371 |
361 | 372 |
362 Object** SerializedScopeInfo::ContextEntriesAddr() { | 373 Object** SerializedScopeInfo::ContextEntriesAddr() { |
363 ASSERT(length() > 0); | 374 ASSERT(length() > 0); |
364 // +3 for function name, calls eval, strict mode. | 375 // +4 for function name, calls eval, strict mode, scope type. |
365 return data_start() + 3; | 376 return data_start() + 4; |
366 } | 377 } |
367 | 378 |
368 | 379 |
369 Object** SerializedScopeInfo::ParameterEntriesAddr() { | 380 Object** SerializedScopeInfo::ParameterEntriesAddr() { |
370 ASSERT(length() > 0); | 381 ASSERT(length() > 0); |
371 Object** p = ContextEntriesAddr(); | 382 Object** p = ContextEntriesAddr(); |
372 int number_of_context_slots; | 383 int number_of_context_slots; |
373 p = ReadInt(p, &number_of_context_slots); | 384 p = ReadInt(p, &number_of_context_slots); |
374 return p + number_of_context_slots*2; // *2 for pairs | 385 return p + number_of_context_slots*2; // *2 for pairs |
375 } | 386 } |
(...skipping 23 matching lines...) Expand all Loading... |
399 if (length() > 0) { | 410 if (length() > 0) { |
400 Object** p = data_start() + 2; // +2 for function name, calls eval. | 411 Object** p = data_start() + 2; // +2 for function name, calls eval. |
401 bool strict_mode; | 412 bool strict_mode; |
402 p = ReadBool(p, &strict_mode); | 413 p = ReadBool(p, &strict_mode); |
403 return strict_mode; | 414 return strict_mode; |
404 } | 415 } |
405 return false; | 416 return false; |
406 } | 417 } |
407 | 418 |
408 | 419 |
| 420 ScopeType SerializedScopeInfo::Type() { |
| 421 ASSERT(length() > 0); |
| 422 // +3 for function name, calls eval, strict mode. |
| 423 Object** p = data_start() + 3; |
| 424 ScopeType type; |
| 425 p = ReadInt(p, &type); |
| 426 return type; |
| 427 } |
| 428 |
| 429 |
409 int SerializedScopeInfo::NumberOfStackSlots() { | 430 int SerializedScopeInfo::NumberOfStackSlots() { |
410 if (length() > 0) { | 431 if (length() > 0) { |
411 Object** p = StackSlotEntriesAddr(); | 432 Object** p = StackSlotEntriesAddr(); |
412 int number_of_stack_slots; | 433 int number_of_stack_slots; |
413 ReadInt(p, &number_of_stack_slots); | 434 ReadInt(p, &number_of_stack_slots); |
414 return number_of_stack_slots; | 435 return number_of_stack_slots; |
415 } | 436 } |
416 return 0; | 437 return 0; |
417 } | 438 } |
418 | 439 |
(...skipping 13 matching lines...) Expand all Loading... |
432 if (length() > 0) { | 453 if (length() > 0) { |
433 Object** p = ContextEntriesAddr(); | 454 Object** p = ContextEntriesAddr(); |
434 int number_of_context_slots; | 455 int number_of_context_slots; |
435 ReadInt(p, &number_of_context_slots); | 456 ReadInt(p, &number_of_context_slots); |
436 return number_of_context_slots > 0; | 457 return number_of_context_slots > 0; |
437 } | 458 } |
438 return false; | 459 return false; |
439 } | 460 } |
440 | 461 |
441 | 462 |
| 463 bool SerializedScopeInfo::HasContext() { |
| 464 return HasHeapAllocatedLocals() || |
| 465 Type() == WITH_SCOPE; |
| 466 } |
| 467 |
| 468 |
442 int SerializedScopeInfo::StackSlotIndex(String* name) { | 469 int SerializedScopeInfo::StackSlotIndex(String* name) { |
443 ASSERT(name->IsSymbol()); | 470 ASSERT(name->IsSymbol()); |
444 if (length() > 0) { | 471 if (length() > 0) { |
445 // Slots start after length entry. | 472 // Slots start after length entry. |
446 Object** p0 = StackSlotEntriesAddr(); | 473 Object** p0 = StackSlotEntriesAddr(); |
447 int number_of_stack_slots; | 474 int number_of_stack_slots; |
448 p0 = ReadInt(p0, &number_of_stack_slots); | 475 p0 = ReadInt(p0, &number_of_stack_slots); |
449 Object** p = p0; | 476 Object** p = p0; |
450 Object** end = p0 + number_of_stack_slots; | 477 Object** end = p0 + number_of_stack_slots; |
451 while (p != end) { | 478 while (p != end) { |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
632 } | 659 } |
633 #endif // DEBUG | 660 #endif // DEBUG |
634 | 661 |
635 | 662 |
636 // Make sure the classes get instantiated by the template system. | 663 // Make sure the classes get instantiated by the template system. |
637 template class ScopeInfo<FreeStoreAllocationPolicy>; | 664 template class ScopeInfo<FreeStoreAllocationPolicy>; |
638 template class ScopeInfo<PreallocatedStorage>; | 665 template class ScopeInfo<PreallocatedStorage>; |
639 template class ScopeInfo<ZoneListAllocationPolicy>; | 666 template class ScopeInfo<ZoneListAllocationPolicy>; |
640 | 667 |
641 } } // namespace v8::internal | 668 } } // namespace v8::internal |
OLD | NEW |